import ExcelJS from "exceljs";
import { saveAs } from "file-saver";
import type { PropertyAggregate } from "@/src/services/api/properties/dtos";

function formatDate(iso: string): string {
  const date = new Date(iso);
  const dd = String(date.getDate()).padStart(2, "0");
  const mm = String(date.getMonth() + 1).padStart(2, "0");
  const yyyy = date.getFullYear();
  return `${dd}/${mm}/${yyyy}`;
}

function formatBoolean(value: boolean): string {
  return value ? "Sim" : "Não";
}

const HEADERS = [
  "Data",
  "Estado",
  "Cidade",
  "A. Sistema de produção",
  "B1. Área - atividade leiteira",
  "B2. Área - pastagem",
  "B3. Área - silagem",
  "C1. Rebanho - Vacas em Lactação",
  "C2. Rebanho - Vacas Secas",
  "C3. Rebanho - Novilhas",
  "C4. Rebanho - Bezerros",
  "C4. Rebanho - Garrotes",
  "C4. Rebanho - Touros",
  "D1. Produção de leite por dia",
  "D2. Produção de leite por Vaca em Lactação por dia",
  "E1. % gordura no leite",
  "E2. % proteína no leite",
  "F1. Volumoso - kg/ vacas em lactação",
  "F2. Concentrado - kg/ vacas em lactação",
  "F3. Unidade de medida",
  "G. Consumo de Energia por mês",
  "Tem Energia Fotovoltáica?",
  "H1. Licença Ambiental da Atividade Leiteira",
  "H2. Outorga de uso da Água",
  // Water Management (Gestão da Água)
  "1. Mapa Hidráulico",
  "2. Sistema de Medição de Água",
  "3. Frequência de Leitura",
  "4. % de Pontos de Consumo de Água",
  "5. Metas de Redução do Consumo ou Perda de Água",
  "6. Sistema de Controle de Vazão de Água Ordenha",
  "7. Boias de Nível nos Bebedouros",
  "8. Boias de Nível nas Estruturas de Armazenamento",
  "9. Rotina de Identificação de Vazamentos",
  "10. Irrigação",
  "11. Resfriamento",
  "12. Captação de Água da Chuva Cisterna?",
  "13. Reúso da Água ou de Efluentes",
  // Water Quality Conservation (Qualidade e Conservação da Água)
  "14. Monitora a Qualidade",
  "15. % de Pontos de Água Monitorados",
  "16. Análise de Nitrato",
  "17. Análise de Escherichia Coli",
  "18. Animais tem Acesso a Corpos D'Água",
  "19. Água de Dessedentação",
  "20. Acúmulo de Água ou Lama",
  "21. Frequência de Limpeza dos Bebedouros",
  // Waste Management (Gestão de Resíduos)
  "22. Sistema de Armazenamento ou Tratamento do Dejeto",
  "23. Sistema Impermeabilizado",
  "24. Águas de Chuva Desviadas",
  "25. Vazamentos nos Sistemas",
  "26. Calhas no Telhado",
  "27. % de Lavagens do Piso",
  "28. Raspagem do Esterco",
  "29. Água com Pressão na Lavagem",
  "30. Plano de Emergência",
  "31. Documenta e Monitora Fertilizantes",
  "32. Análise Laboratorial Resíduo Orgânico",
  "33. Análise do Solo",
  "34. Periodicidade de Aplicação dos Resíduos como Adubo",
  "35. Forma de Aplicação dos Resíduos no Solo",
  // Meso Indices
  "Consumo Água",
  "Perdas Água",
  "Segurança Hídrica",
  "Análise Água",
  "Conservação Água",
  "Estrutura",
  "Manejo de Resíduo",
  "Adubação",
  // Macro Indices
  "Quantidade Água",
  "Qualidade Água",
  "Manejo Resíduos",
  // IDH
  "IDH",
  "Índice de Desempenho Hídrico (IDH)",
];

function formatNumber(value: number | null | undefined): string | number {
  if (value === null || value === undefined) return "";

  return Math.round(value * 100) / 100;
}

function propertyToRow(aggregate: PropertyAggregate): (string | number)[] {
  const { property, waterManagement, waterQualityConservation, wasteManagement, waterPerformanceIndex, meso } =
    aggregate;

  return [
    formatDate(property.createdAt),
    property.state ?? "",
    property.city ?? "",
    property.productionSystem,
    formatNumber(property.totalAreaHa),
    formatNumber(property.pastureAreaHa),
    formatNumber(property.silageAreaHa),
    formatNumber(property.lactatingCows),
    formatNumber(property.dryCows),
    formatNumber(property.heifersOver12m),
    formatNumber(property.calvesUnder12m),
    formatNumber(property.steers),
    formatNumber(property.bulls),
    formatNumber(property.milkLitersPerDayProperty),
    formatNumber(property.milkLitersPerCowDay),
    formatNumber(property.milkFatPercentage),
    formatNumber(property.milkProteinPercentage),
    formatNumber(property.roughageKgPerCow),
    formatNumber(property.concentrateKgPerCow),
    property.feedUnit,
    formatNumber(property.monthlyEnergyKwh),
    formatBoolean(property.hasPhotovoltaicEnergy),
    property.hasEnvironmentalLicense ?? "",
    property.hasWaterGrant ?? "",
    // Water Management
    formatNumber(waterManagement?.hasHydraulicMapScore),
    formatNumber(waterManagement?.hasWaterMeasurementScore),
    formatNumber(waterManagement?.measurementFrequencyScore),
    formatNumber(waterManagement?.monitoredConsumptionScore),
    formatNumber(waterManagement?.hasReductionGoalsScore),
    formatNumber(waterManagement?.hasFlowControlSystemScore),
    formatNumber(waterManagement?.hasLevelFloatDrinkersScore),
    formatNumber(waterManagement?.hasLevelFloatStorageScore),
    formatNumber(waterManagement?.leakIdentificationScore),
    formatNumber(waterManagement?.irrigationProgramScore),
    formatNumber(waterManagement?.coolingSystemScore),
    formatNumber(waterManagement?.rainwaterHarvestScore),
    formatNumber(waterManagement?.waterReuseScore),
    // Water Quality Conservation
    formatNumber(waterQualityConservation?.monitorsQualityScore),
    formatNumber(waterQualityConservation?.monitoredWaterPointsPercentScore),
    formatNumber(waterQualityConservation?.nitrateAnalysisScore),
    formatNumber(waterQualityConservation?.ecoliAnalysisScore),
    formatNumber(waterQualityConservation?.animalsAccessWaterBodiesScore),
    formatNumber(waterQualityConservation?.drinkerWaterSupplyScore),
    formatNumber(waterQualityConservation?.waterAccumulationAreasScore),
    formatNumber(waterQualityConservation?.drinkerCleaningFrequencyScore),
    // Waste Management
    formatNumber(wasteManagement?.wasteStorageSystemScore),
    formatNumber(wasteManagement?.impermeabilizedSystemScore),
    formatNumber(wasteManagement?.rainwaterDivertedScore),
    formatNumber(wasteManagement?.systemLeaksScore),
    formatNumber(wasteManagement?.roofGuttersScore),
    formatNumber(wasteManagement?.floorWashingPercentageScore),
    formatNumber(wasteManagement?.manureRakingScore),
    formatNumber(wasteManagement?.pressureWashingScore),
    formatNumber(wasteManagement?.emergencyPlanScore),
    formatNumber(wasteManagement?.fertilizerDocumentationScore),
    formatNumber(wasteManagement?.organicResidueLabScore),
    formatNumber(wasteManagement?.soilAnalysisScore),
    formatNumber(wasteManagement?.residueApplicationFrequencyScore),
    formatNumber(wasteManagement?.residueApplicationMethodScore),
    // Meso Indices
    formatNumber(meso.consumoAgua),
    formatNumber(meso.perdasAgua),
    formatNumber(meso.segurancaHidrica),
    formatNumber(meso.qualidadeAgua),
    formatNumber(meso.conservacaoAgua),
    formatNumber(meso.estrutura),
    formatNumber(meso.manejoResiduo),
    formatNumber(meso.adubacao),
    // Macro Indices
    formatNumber(waterPerformanceIndex?.waterManagementScore),
    formatNumber(waterPerformanceIndex?.waterQualityConservationScore),
    formatNumber(waterPerformanceIndex?.wasteManagementScore),
    // IDH
    waterPerformanceIndex?.finalScore !== undefined && waterPerformanceIndex?.finalScore !== null ? "" : "Vazio",
    formatNumber(waterPerformanceIndex?.finalScore),
  ];
}

export async function downloadPropertiesXlsx(
  properties: PropertyAggregate[],
): Promise<void> {
  if (!properties || properties.length === 0) {
    console.warn("No properties to export");
    return;
  }

  const workbook = new ExcelJS.Workbook();
  const worksheet = workbook.addWorksheet("Propriedades");

  const headerRow = worksheet.addRow(HEADERS);

  headerRow.eachCell((cell) => {
    cell.fill = {
      type: "pattern",
      pattern: "solid",
      fgColor: { argb: "FF4EA72E" },
    };
    cell.font = {
      bold: true,
      color: { argb: "FFFFFFFF" },
      size: 11,
    };
    cell.alignment = { vertical: "middle", horizontal: "center", wrapText: true };
    cell.border = {
      top: { style: "thin", color: { argb: "FFB7B7B7" } },
      bottom: { style: "thin", color: { argb: "FFB7B7B7" } },
      left: { style: "thin", color: { argb: "FFB7B7B7" } },
      right: { style: "thin", color: { argb: "FFB7B7B7" } },
    };
  });

  const rows = properties.map(propertyToRow);

  rows.forEach((rowData, index) => {
    const row = worksheet.addRow(rowData);
    const isEvenRow = index % 2 === 0;

    row.eachCell((cell) => {
      cell.fill = {
        type: "pattern",
        pattern: "solid",
        fgColor: { argb: isEvenRow ? "FFDAF2D0" : "FFFFFFFF" },
      };
      cell.font = { size: 11 };
      cell.alignment = { vertical: "middle", horizontal: "center" };
      cell.border = {
        top: { style: "thin", color: { argb: "FFB7B7B7" } },
        bottom: { style: "thin", color: { argb: "FFB7B7B7" } },
        left: { style: "thin", color: { argb: "FFB7B7B7" } },
        right: { style: "thin", color: { argb: "FFB7B7B7" } },
      };
    });
  });

  worksheet.columns.forEach((column, colIndex) => {
    const headerLength = HEADERS[colIndex]?.length ?? 10;
    let maxLength = headerLength;

    rows.forEach((row) => {
      const cellValue = String(row[colIndex] ?? "");
      if (cellValue.length > maxLength) {
        maxLength = cellValue.length;
      }
    });

    column.width = Math.min(maxLength + 4, 50);
  });

  const buffer = await workbook.xlsx.writeBuffer();
  const blob = new Blob([buffer], {
    type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
  });
  saveAs(blob, "propriedades.xlsx");
}
