using Brizco.Domain.Entities.Tasks;
using Task = System.Threading.Tasks.Task;

namespace Brizco.Core.CoreServices.ReportServices;
public class TaskReportCommandHandler : IRequestHandler<TaskReportCommand , byte[]>
{
    private readonly IRepositoryWrapper _repositoryWrapper;

    public TaskReportCommandHandler(IRepositoryWrapper repositoryWrapper)
    {
        _repositoryWrapper = repositoryWrapper;
    }
    public async Task<byte[]> Handle(TaskReportCommand request, CancellationToken cancellationToken)
    {
        var tasks = await _repositoryWrapper.SetRepository<Domain.Entities.Tasks.Task>()
            .TableNoTracking
            .Select(TaskMapper.ProjectToLDto)
            .ToListAsync(cancellationToken);

        var workbook = new XSSFWorkbook();

        var sheet = workbook.CreateSheet("روزانه");

        sheet.IsRightToLeft = true;
        int selectedRow = 1;
        var originalTasks = tasks.Where(t => t.ScheduleType == TaskScheduleType.Daily).ToList();

        CreateHeader(sheet, workbook);

        var shiftsTask = originalTasks.SelectMany(dt => dt.Shifts).ToList();
        foreach (var taskShiftGrouped in shiftsTask.GroupBy(t => t.ShiftId))
        {
            var count = taskShiftGrouped.ToList().Count - 1;
            var shiftName = taskShiftGrouped.FirstOrDefault()?.ShiftName ?? string.Empty;
            CreateShiftName(selectedRow, selectedRow + count, shiftName, sheet, workbook);
            int j = selectedRow;
            foreach (var taskShiftSDto in taskShiftGrouped)
            {
                var row = sheet.GetRow(j) ?? sheet.CreateRow(j);
                row.Height = 700;

                var style = workbook.CreateCellStyle();

                style.VerticalAlignment = VerticalAlignment.Center;
                style.Alignment = HorizontalAlignment.Center;
                style.WrapText = true;

                var cell = row.CreateCell(1);
                cell.CellStyle = style;
                cell.SetCellValue(taskShiftSDto.TaskTitle);


                var position = await _repositoryWrapper.SetRepository<TaskPosition>()
                    .TableNoTracking
                    .Where(t => t.TaskId == taskShiftSDto.TaskId)
                    .Select(TaskPositionMapper.ProjectToSDto)
                    .ToListAsync(cancellationToken);

                var positionCell = row.CreateCell(2);
                positionCell.CellStyle = style;
                positionCell.SetCellValue(string.Join(" , ", position.Select(p => p.PositionName)));

                j++;
            }

            selectedRow += count + 1;
        }

        sheet.SetColumnWidth(1, 25600);
        sheet.SetColumnWidth(2, 7000);
        await CreateSheetForWeek(tasks, 6, workbook);
        for (int i = 0; i < 6; i++)
        {
            await CreateSheetForWeek(tasks, i, workbook);
        }





        var stream = new MemoryStream();
        workbook.Write(stream);
        var content = stream.ToArray();

        return content;
    }

    async Task CreateSheetForWeek(List<TaskLDto> tasks, int day, XSSFWorkbook workbook)
    {
        var dayOfWeek = (DayOfWeek)day;
        var sheet = workbook.CreateSheet(dayOfWeek.GetPersianDayOfWeek());

        int selectedRow = 1;

        CreateHeader(sheet, workbook);

        sheet.IsRightToLeft = true;
        var dayTasks = tasks.Where(t => t.Days.Any(d => d.DayOfWeek == (DayOfWeek)day)).ToList();



        var shiftsTask = dayTasks.SelectMany(dt => dt.Shifts).ToList();
        foreach (var taskShiftGrouped in shiftsTask.GroupBy(t => t.ShiftId))
        {
            var count = taskShiftGrouped.ToList().Count - 1;
            var shiftName = taskShiftGrouped.FirstOrDefault()?.ShiftName ?? string.Empty;
            CreateShiftName(selectedRow, selectedRow + count, shiftName, sheet, workbook);
            int j = selectedRow;
            foreach (var taskShiftSDto in taskShiftGrouped)
            {

                var row = sheet.GetRow(j) ?? sheet.CreateRow(j);
                row.Height = 700;

                var style = workbook.CreateCellStyle();

                style.VerticalAlignment = VerticalAlignment.Center;
                style.Alignment = HorizontalAlignment.Center;
                style.WrapText = true;

                var cell = row.CreateCell(1);
                cell.CellStyle = style;
                cell.SetCellValue(taskShiftSDto.TaskTitle);


                var position = await _repositoryWrapper.SetRepository<TaskPosition>()
                    .TableNoTracking
                    .Where(t => t.TaskId == taskShiftSDto.TaskId)
                    .Select(TaskPositionMapper.ProjectToSDto)
                    .ToListAsync();

                var positionCell = row.CreateCell(2);
                positionCell.CellStyle = style;
                positionCell.SetCellValue(string.Join(" , ", position.Select(p => p.PositionName)));

                j++;
            }

            selectedRow = (selectedRow) + count + 1;
        }
        sheet.SetColumnWidth(1, 25600);
        sheet.SetColumnWidth(2, 7000);
    }

    void CreateHeader(ISheet sheet, XSSFWorkbook workbook)
    {
        var headerRow = sheet.GetRow(0) ?? sheet.CreateRow(0);
        headerRow.Height = 700;

        var font = workbook.CreateFont();
        font.IsBold = true;
        font.Color = NPOI.HSSF.Util.HSSFColor.White.Index;

        //font.FontHeight = 16;
        var style = workbook.CreateCellStyle();
        style.Alignment = HorizontalAlignment.Center;
        style.VerticalAlignment = VerticalAlignment.Center;
        style.WrapText = true;
        style.SetFont(font);

        byte[] rgb = new byte[3] { 30, 81, 123 };
        XSSFColor color = new XSSFColor(rgb);
        //style.SetFillBackgroundColor(color);
        //style.SetFillForegroundColor(color);

        style.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.BlueGrey.Index;
        style.FillPattern = FillPattern.SolidForeground;

        var shiftNameHeaderCell = headerRow.CreateCell(0);
        shiftNameHeaderCell.CellStyle = style;
        shiftNameHeaderCell.SetCellValue("شیفتــ");

        var taskNameHeaderCell = headerRow.CreateCell(1);
        taskNameHeaderCell.CellStyle = style;
        taskNameHeaderCell.SetCellValue("تسکــــ");

        var positionNameHeaderCell = headerRow.CreateCell(2);
        positionNameHeaderCell.CellStyle = style;
        positionNameHeaderCell.SetCellValue("پوزیشن");
    }

    void CreateShiftName(int startRow, int lastRow, string name, ISheet sheet, XSSFWorkbook workbook)
    {
        var style = workbook.CreateCellStyle();
        var font = workbook.CreateFont();
        font.IsBold = true;
        style.Alignment = HorizontalAlignment.Center;
        style.VerticalAlignment = VerticalAlignment.Center;
        style.WrapText = true;
        style.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.Gold.Index;
        style.FillPattern = FillPattern.SolidForeground;

        style.BorderTop = BorderStyle.Dashed;
        style.TopBorderColor = NPOI.HSSF.Util.HSSFColor.BlueGrey.Index;

        style.SetFont(font);
        if (lastRow > startRow)
        {
            sheet.AddMergedRegion(new CellRangeAddress(startRow, lastRow, 0, 0));

            var rowHeader = sheet.CreateRow(startRow);
            style.Rotation = 90;
            var cell = rowHeader.CreateCell(0);
            cell.SetCellValue(name);
            cell.CellStyle = style;

        }
        else
        {
            var rowHeader = sheet.CreateRow(startRow);

            var cell = rowHeader.CreateCell(0);
            cell.SetCellValue(name);
            cell.CellStyle = style;
        }
    }
}
