using AsbCloudApp.Data.DrillTestReport;
using ClosedXML.Excel;
using System;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using AsbCloudApp.Services;

namespace AsbCloudInfrastructure.Services.DrillTestReport;

public class DrillTestReportMakerService : IReportMakerService<DrillTestReportDataDto>
{
    private readonly string templateName = "DrillTestReportTemplate.xlsx";
    private readonly string sheetName = "Лист1";
    private readonly int startRowNumber = 8;

    public Stream MakeReport(DrillTestReportDataDto report)
    {
        using var excelTemplateStream = Assembly.GetExecutingAssembly().GetTemplateCopyStream(templateName);

        using var workbook = new XLWorkbook(excelTemplateStream);

        AddToWorkbook(workbook, report);

        MemoryStream memoryStream = new MemoryStream();
        workbook.SaveAs(memoryStream, new SaveOptions { });
        memoryStream.Seek(0, SeekOrigin.Begin);

        return memoryStream;
    }
    
    private void AddToWorkbook(XLWorkbook workbook, DrillTestReportDataDto report)
    {
        var drillTests = report.Data.Params;
        
        if (!drillTests.Any())
            return;

        var sheet = workbook.GetWorksheet(sheetName);

        sheet.Cell(4, 2).SetCellValue(report.Caption);
        sheet.Cell(5, 2).SetCellValue(report.Date);
        
        var stepWithMaxDepthSpeed = drillTests.MaxBy(p => p.DepthSpeed)!.Step;
        var startDepth = report.Data.DepthStart;
        var startDate = report.Data.TimeStampStart;

        var rowNumber = startRowNumber;
        
        foreach (var drillTestEntity in drillTests)
        {
            var endDepth = startDepth + (drillTestEntity.DepthDrillStep ?? 0);
            var endDateTime = startDate.AddSeconds(drillTestEntity.TimeDrillStep ?? 0);
            
            sheet.Cell(rowNumber, 2).SetCellValue(startDepth);
            sheet.Cell(rowNumber, 3).SetCellValue(endDepth);
            sheet.Cell(rowNumber, 4).SetCellValue(drillTestEntity.DepthDrillStep);
            sheet.Cell(rowNumber, 5).SetCellValue(drillTestEntity.Workload);
            sheet.Cell(rowNumber, 6).SetCellValue(drillTestEntity.Speed);
            sheet.Cell(rowNumber, 7).SetCellValue(startDate.DateTime);
            sheet.Cell(rowNumber, 8).SetCellValue(endDateTime.DateTime);
            sheet.Cell(rowNumber, 9).SetCellValue(Math.Round((drillTestEntity.TimeDrillStep ?? 0) / (60 * 60), 2));
            sheet.Cell(rowNumber, 10).SetCellValue(drillTestEntity.DepthSpeed);

            if (drillTestEntity.Step == stepWithMaxDepthSpeed)
            {
                var currentCells = sheet.Row(rowNumber).Cells(1, 10);
                currentCells.Style.Fill.BackgroundColor = XLColor.Yellow;
            }

            startDepth = endDepth;
            startDate = endDateTime;
            rowNumber++;
        }
    }
}