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

namespace AsbCloudInfrastructure.Services.DrillingProgram;


public class TitleListSheet 
{
    private const string directionDirectorPositionName = "Руководитель направления по ТСБ";

    private readonly DateTimeOffset 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?.User 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 static void DrawAccept(IXLWorksheet sheet, FileMarkDto mark, (int row, int col) startAddress)
    {            
        var user = mark.User;
        if(user is null)
            return;

        int startRow = startAddress.row;
        int startCol = startAddress.col;

        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(DateTimeOffset dateTime)
        => $"{dateTime.Day:00}.{dateTime.Month:00}.{dateTime.Year:00}";
}