using AsbCloudApp.Data;
using ClosedXML.Excel;
using System;
using System.Collections.Generic;
using System.Linq;

namespace AsbCloudInfrastructure.Services.DrillingProgram
{
#nullable enable
    public class TitleListSheet 
    {
        private const string directionDirectorPositionName = "Руководитель направления по ТСБ";

        private readonly DateTime totalDate;
        private readonly FileMarkDto? acceptDirectionDirector;
        private readonly List<FileMarkDto> acceptsOthers;
        private readonly WellDto well;

        public TitleListSheet(IEnumerable<FileMarkDto> fileMarks, WellDto well)
        {
            totalDate = fileMarks.Max(f => f.DateCreated);
            acceptDirectionDirector = fileMarks
                .OrderByDescending(f => f.DateCreated)
                .FirstOrDefault(f => f.User.Position == directionDirectorPositionName);
            acceptsOthers = fileMarks
                .Where(f => f.Id != acceptDirectionDirector?.Id)
                .OrderBy(f => f.DateCreated)
                .ToList();
            this.well = well;
        }

        public void Draw(IXLWorksheet sheet)
        {
            const double santimetr = 0.393701;
            sheet.Style.Font.FontName = "Calibri";
            sheet.Style.Font.FontSize = 12;
            sheet.PageSetup.PaperSize = XLPaperSize.A4Paper;
            sheet.PageSetup.Margins
                .SetTop(santimetr)
                .SetLeft(2 * santimetr)
                .SetBottom(santimetr)
                .SetRight(santimetr);

            DrawTopRightSign(sheet);
            DrawMainTilte(sheet);
            DrawOtherAcceptors(sheet);

            sheet.Range(51, 1, 51, 5)
                .Merge()
                .SetValue($"{totalDate.Year:00}")
                .Style.Alignment.SetHorizontal(XLAlignmentHorizontalValues.Center);

            var k = 4.95867768595041;
            sheet.Column(1).Width = k*2.3;
            sheet.Column(2).Width = k*6;
            sheet.Column(3).Width = k*0.53; 
            sheet.Column(4).Width = k*2.3;
            sheet.Column(5).Width = k*6;
        }

        private void DrawTopRightSign(IXLWorksheet sheet)
        {
            if (acceptDirectionDirector is null)
                return;

            var user = acceptDirectionDirector.User;

            sheet.Cell(1, 5)
                .SetValue("Согласовано:");

            sheet.Cell(2, 5)
                .SetValue(user.Position);

            sheet.Cell(3, 5)
                .SetValue(user.Company?.Caption);

            sheet.Cell(4, 5)
                .SetValue($"{user.Surname} {user.Name} {user.Patronymic}");

            sheet.Cell(5, 5)
                .SetValue(FormatDate(acceptDirectionDirector.DateCreated));

            sheet.Range(1,5, 5,5).Style.Alignment
                .SetHorizontal(XLAlignmentHorizontalValues.Right);
        }

        private void DrawMainTilte(IXLWorksheet sheet)
        {
            sheet.Range(11, 1, 11, 5)
                .Merge()
                .SetValue($"Программа на бурение скважины №{well.Caption}, куст №{well.Cluster}");

            sheet.Range(12, 1, 12, 5)
                .Merge()
                .SetValue($"{well.Deposit} месторождения");

            sheet.Range(11, 1, 12, 5).Style
                .Alignment.SetHorizontal(XLAlignmentHorizontalValues.Center)
                .Font.SetFontSize(14)
                .Font.SetBold(true);
        }

        private void DrawOtherAcceptors(IXLWorksheet sheet)
        {
            const int baseRow = 16;
            const int deltaRow = 7;
            (int row, int col)[] addresses =
            {
                (baseRow + 4 * deltaRow, 4), (baseRow + 4 * deltaRow, 1),
                (baseRow + 3 * deltaRow, 4), (baseRow + 3 * deltaRow, 1),
                (baseRow + 2 * deltaRow, 4), (baseRow + 2 * deltaRow, 1),
                (baseRow + 1 * deltaRow, 4), (baseRow + 1 * deltaRow, 1),
                (baseRow + 0 * deltaRow, 4), (baseRow + 0 * deltaRow, 1),
            };
            var i = 0;
            for (; i < acceptsOthers.Count && i < 10; i++)
                DrawAccept(sheet, acceptsOthers[i], addresses[i]);

            sheet.Cell(addresses[i-1].row - 2, 1)
                .SetValue("Утверждаю:");
        }

        private void DrawAccept(IXLWorksheet sheet, FileMarkDto mark, (int row, int col) startAddress)
        {
            int startRow = startAddress.row;
            int startCol = startAddress.col;
            var user = mark.User;
            sheet.Cell(startRow, startCol)
                .SetValue("Должность");

            sheet.Range(startRow, startCol + 1, startRow + 1, startCol + 1)
                .Merge()
                .SetValue(user.Position);
               
            sheet.Cell(startRow + 2, startCol)
                .SetValue("Компания");

            sheet.Range(startRow + 2, startCol + 1, startRow + 3, startCol + 1)
                .Merge()
                .SetValue(user.Company?.Caption);

            sheet.Range(startRow + 4, startCol, startRow + 4, startCol + 1)
                .Merge()
                .SetValue($"{user.Surname} {user.Name} {user.Patronymic}");

            sheet.Range(startRow + 5, startCol, startRow + 5, startCol + 1)
                .Merge()
                .SetValue(FormatDate(mark.DateCreated));

            sheet.Range(startRow, startCol, startRow + 5, startCol + 1)
                .Style.Border.SetOutsideBorder(XLBorderStyleValues.Thin)
                .Alignment.SetVertical(XLAlignmentVerticalValues.Top)
                .Alignment.SetHorizontal(XLAlignmentHorizontalValues.Left);
        }

        private static string FormatDate(DateTime dateTime)
            => $"{dateTime.Day:00}.{dateTime.Month:00}.{dateTime.Year:00}";
    }
#nullable disable
}