using ClosedXML.Excel;

namespace Eis.Infrastructure.Administration;

internal sealed record AdminResultExportRow(
    string CandidateNumber,
    string CardNumber,
    string CandidateName,
    string SchoolName,
    string ClassName,
    string ExamCode,
    string ExamName,
    string SubjectName,
    object FullScore,
    string PassRule,
    object PassScore,
    object Score,
    object Rank,
    object RankPercent,
    string Qualified,
    string Grade,
    string Published,
    string UpdatedAt);

internal static class AdminResultExporter
{
    private static readonly string[] Headers =
    [
        "报名号*", "准考证号（只读参考）", "姓名（只读参考）", "学校（只读参考）", "班级（只读参考）",
        "考试代码*", "考试名称（只读参考）", "科目*", "科目满分（只读参考）", "单科及格规则（只读参考）",
        "实际及格分（只读参考）", "成绩*", "本科排名（导出计算）", "排名百分位（导出计算）",
        "单科达线（导出计算）", "排名等级（自动计算）", "发布状态*", "更新时间（只读参考）"
    ];

    public static byte[] Build(IReadOnlyList<AdminResultExportRow> rows)
    {
        using var workbook = new XLWorkbook();
        var sheet = workbook.Worksheets.Add("成绩");
        sheet.Cell(1, 1).Value = "考试成绩台账";
        sheet.Range(1, 1, 1, Headers.Length).Merge();
        sheet.Range(1, 1, 1, Headers.Length).Style
            .Font.SetBold().Font.SetFontSize(16).Font.SetFontColor(XLColor.White)
            .Fill.SetBackgroundColor(XLColor.FromHtml("#182552"));
        for (var index = 0; index < Headers.Length; index++)
        {
            sheet.Cell(2, index + 1).Value = Headers[index];
        }
        sheet.Range(2, 1, 2, Headers.Length).Style
            .Font.SetBold().Font.SetFontColor(XLColor.White)
            .Fill.SetBackgroundColor(XLColor.FromHtml("#245365"));
        for (var rowIndex = 0; rowIndex < rows.Count; rowIndex++)
        {
            var item = rows[rowIndex];
            object[] values =
            [
                item.CandidateNumber, item.CardNumber, item.CandidateName, item.SchoolName, item.ClassName,
                item.ExamCode, item.ExamName, item.SubjectName, item.FullScore, item.PassRule, item.PassScore,
                item.Score, item.Rank, item.RankPercent, item.Qualified, item.Grade, item.Published, item.UpdatedAt
            ];
            for (var column = 0; column < values.Length; column++)
            {
                sheet.Cell(rowIndex + 3, column + 1).Value = XLCellValue.FromObject(values[column]);
            }
        }
        sheet.SheetView.FreezeRows(2);
        sheet.RangeUsed()?.SetAutoFilter();
        double[] widths =
        [
            24, 22, 14, 22, 16, 18, 26, 14, 16, 22, 18, 12, 16, 18, 16, 18, 14, 22
        ];
        for (var index = 0; index < widths.Length; index++)
        {
            sheet.Column(index + 1).Width = widths[index];
        }
        sheet.Columns(9, 14).Style.NumberFormat.Format = "0.00";
        using var stream = new MemoryStream();
        workbook.SaveAs(stream);
        return stream.ToArray();
    }
}
