using ClosedXML.Excel;
using System.Data;
using System.Globalization;

namespace Contime.data {
    public class ExcelExporter {
        private readonly DataAccess _dataAccess;

        public ExcelExporter(DataAccess dataAccess) {
            _dataAccess = dataAccess;
        }

        public void Export(string filePath) {
            var allTimeEntries = _dataAccess.GetAllTimeEntriesForExport();
            if (!allTimeEntries.Any()) {
                // Handle case with no data
                return;
            }

            using (var workbook = new XLWorkbook()) {
                var groupedByWeek = allTimeEntries
                    .GroupBy(entry => GetIso8601WeekOfYear(entry.Date))
                    .OrderBy(g => g.Key);

                foreach (var weekGroup in groupedByWeek) {
                    var weekNumber = weekGroup.Key;
                    var worksheet = workbook.Worksheets.Add($"KW {weekNumber}");

                    // --- Header ---
                    worksheet.Cell("A1").Value = "Date";
                    worksheet.Cell("B1").Value = "Task Description";
                    worksheet.Cell("C1").Value = "Duration (hh:mm:ss)";
                    var headerRange = worksheet.Range("A1:C1");
                    headerRange.Style.Font.Bold = true;
                    headerRange.Style.Fill.BackgroundColor = XLColor.LightGray;

                    int currentRow = 2;
                    var groupedByDay = weekGroup.GroupBy(entry => entry.Date.Date).OrderBy(g => g.Key);

                    foreach (var dayGroup in groupedByDay) {
                        foreach (var entry in dayGroup) {
                            worksheet.Cell(currentRow, 1).Value = entry.Date.ToString("yyyy-MM-dd");
                            worksheet.Cell(currentRow, 2).Value = entry.TaskName;
                            worksheet.Cell(currentRow, 3).Value = entry.Duration.ToString(@"hh\:mm\:ss");
                            currentRow++;
                        }
                    }

                    worksheet.Columns().AdjustToContents();
                }

                workbook.SaveAs(filePath);
            }
        }

        private static int GetIso8601WeekOfYear(DateTime time) {
            DayOfWeek day = CultureInfo.InvariantCulture.Calendar.GetDayOfWeek(time);
            if (day >= DayOfWeek.Monday && day <= DayOfWeek.Wednesday) {
                time = time.AddDays(3);
            }
            return CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(time, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
        }
    }
}
