"use client";

import {
  Dialog,
  DialogBackdrop,
  DialogPanel,
  DialogTitle,
  Transition,
} from "@headlessui/react";
import { Fragment, useMemo } from "react";

/* ------------------------------------------------
 Types
------------------------------------------------ */

interface ScenarioMeasuresModalProps {
  isOpen: boolean;
  onClose: () => void;
  isLoading: boolean;
  data: any | null;
  error: unknown;
}

type ScenarioMeasure = {
  measureType: string;
  homesCount: number;
  totalCost: number;
  averageCost: number;
};

export type MeasureCategory =
  | "Wall insulation"
  | "Roof insulation"
  | "Floor insulation"
  | "Ventilation & airtightness"
  | "Windows & glazing"
  | "Solar"
  | "Heating"
  | "Heating controls"
  | "Lighting"
  | "Scaffolding & enabling works"
  | "Other";

/* ------------------------------------------------
 Category mapping
------------------------------------------------ */

export const MEASURE_CATEGORY_MAP: Record<string, MeasureCategory> = {
  internal_wall_insulation: "Wall insulation",
  external_wall_insulation: "Wall insulation",
  cavity_wall_insulation: "Wall insulation",
  cavity_wall_extraction: "Wall insulation",

  loft_insulation: "Roof insulation",
  flat_roof_insulation: "Roof insulation",
  room_roof_insulation: "Roof insulation",

  suspended_floor_insulation: "Floor insulation",
  solid_floor_insulation: "Floor insulation",
  exposed_floor_insulation: "Floor insulation",

  mechanical_ventilation: "Ventilation & airtightness",
  trickle_vent: "Ventilation & airtightness",
  door_undercut: "Ventilation & airtightness",
  sealing_fireplace: "Ventilation & airtightness",

  windows_glazing: "Windows & glazing",
  double_glazing: "Windows & glazing",
  secondary_glazing: "Windows & glazing",

  solar_pv: "Solar",
  solar_battery: "Solar",

  air_source_heat_pump: "Heating",
  boiler_upgrade: "Heating",
  high_heat_retention_storage_heaters: "Heating",

  roomstat_programmer_trvs: "Heating controls",
  time_temperature_zone_control: "Heating controls",

  low_energy_lighting_installation: "Lighting",

  scaffolding: "Scaffolding & enabling works",
};

function getMeasureCategory(measureType: string): MeasureCategory {
  return MEASURE_CATEGORY_MAP[measureType] ?? "Other";
}

/* ------------------------------------------------
 Helpers
------------------------------------------------ */

function toTitleCase(value: string) {
  return value
    .replaceAll("_", " ")
    .toLowerCase()
    .replace(/\b\w/g, (char) => char.toUpperCase());
}

type GroupedMeasures = {
  category: MeasureCategory;
  rows: ScenarioMeasure[];
  homesTotal: number;
  costTotal: number;
};

function groupMeasuresByCategory(
  measures: ScenarioMeasure[]
): GroupedMeasures[] {
  const map = new Map<MeasureCategory, ScenarioMeasure[]>();

  for (const m of measures) {
    const category = getMeasureCategory(m.measureType);
    if (!map.has(category)) map.set(category, []);
    map.get(category)!.push(m);
  }

  return Array.from(map.entries()).map(([category, rows]) => ({
    category,
    rows,
    homesTotal: rows.reduce((s, r) => s + r.homesCount, 0),
    costTotal: rows.reduce((s, r) => s + r.totalCost, 0),
  }));
}

/* ------------------------------------------------
 CSV download
------------------------------------------------ */

function downloadMeasuresCsv(groups: GroupedMeasures[]) {
  const lines: string[] = [];
  lines.push("Category,Measure,Homes,Total cost (£),Average cost (£)");

  for (const group of groups) {
    for (const m of group.rows) {
      lines.push(
        [
          group.category,
          toTitleCase(m.measureType),
          m.homesCount,
          m.totalCost.toFixed(0),
          m.averageCost.toFixed(2),
        ].join(",")
      );
    }

    // Subtotal
    lines.push(
      [
        group.category,
        "Subtotal",
        group.homesTotal,
        group.costTotal.toFixed(0),
        "",
      ].join(",")
    );
  }

  const blob = new Blob([lines.join("\n")], {
    type: "text/csv;charset=utf-8;",
  });

  const url = URL.createObjectURL(blob);
  const link = document.createElement("a");
  link.href = url;
  link.download = "scenario-measures.csv";
  link.click();
}

/* ------------------------------------------------
 Component
------------------------------------------------ */

export function ScenarioMeasuresModal({
  isOpen,
  onClose,
  isLoading,
  data,
  error,
}: ScenarioMeasuresModalProps) {
  const measures = useMemo<ScenarioMeasure[]>(() => data?.measures ?? [], [data?.measures]);

  const grouped = useMemo(() => groupMeasuresByCategory(measures), [measures]);

  return (
    <Transition show={isOpen} as={Fragment}>
      <Dialog
        as="div"
        className="fixed inset-0 z-50 overflow-y-auto"
        onClose={onClose}
      >
        <div className="min-h-screen px-4 text-center">
          {isLoading && (
            <DialogBackdrop className="fixed inset-0 bg-black/30" />
          )}

          <span className="inline-block h-screen align-middle" />

          <DialogPanel className="inline-block w-full max-w-5xl p-6 my-8 text-left align-middle bg-white shadow-xl rounded-2xl">
            <DialogTitle className="text-lg font-semibold text-gray-900">
              Scenario measures
            </DialogTitle>

            {/* Actions */}
            <div className="mt-4 flex items-center justify-between">
              <p className="text-sm text-gray-500">
                {measures.length} measures
              </p>

              <button
                onClick={() => downloadMeasuresCsv(grouped)}
                disabled={!measures.length}
                className="rounded-md border px-3 py-2 text-sm font-medium hover:bg-gray-50 disabled:opacity-50"
              >
                Download CSV
              </button>
            </div>

            {/* Content */}
            <div className="mt-4">
              {isLoading && (
                <div className="text-sm text-gray-500">Loading measures…</div>
              )}

              {Boolean(error) && (
                <div className="text-sm text-red-600">
                  Failed to load measures.
                </div>
              )}

              {!isLoading && grouped.length > 0 && (
                <div className="overflow-x-auto rounded-xl border border-gray-200">
                  <table className="w-full text-sm">
                    <thead className="bg-gray-50">
                      <tr>
                        <th className="px-4 py-2 text-left font-medium text-gray-700">
                          Measure
                        </th>
                        <th className="px-4 py-2 text-right font-medium text-gray-700">
                          Homes
                        </th>
                        <th className="px-4 py-2 text-right font-medium text-gray-700">
                          Total cost
                        </th>
                        <th className="px-4 py-2 text-right font-medium text-gray-700">
                          Avg. cost
                        </th>
                      </tr>
                    </thead>

                    <tbody>
                      {grouped.map((group) => (
                        <Fragment key={group.category}>
                          {/* Category header */}
                          <tr className="bg-gray-100 border-t border-brandmidblue border-b">
                            <td
                              colSpan={4}
                              className="px-4 py-3 text-sm font-semibold text-gray-700 tracking-wide"
                            >
                              {group.category}
                            </td>
                          </tr>

                          {/* Rows */}
                          {group.rows.map((row) => (
                            <tr key={row.measureType} className="border-t">
                              <td className="px-4 py-2">
                                {toTitleCase(row.measureType)}
                              </td>
                              <td className="px-4 py-2 text-right">
                                {row.homesCount.toLocaleString()}
                              </td>
                              <td className="px-4 py-2 text-right">
                                £{row.totalCost.toLocaleString()}
                              </td>
                              <td className="px-4 py-2 text-right text-gray-600">
                                £
                                {row.averageCost.toLocaleString(undefined, {
                                  maximumFractionDigits: 0,
                                })}
                              </td>
                            </tr>
                          ))}

                          {/* Subtotal */}
                          <tr className="border-t bg-gray-50">
                            <td className="px-4 py-2 font-medium text-gray-700">
                              Subtotal
                            </td>
                            <td className="px-4 py-2 text-right font-medium">
                              {group.homesTotal.toLocaleString()}
                            </td>
                            <td className="px-4 py-2 text-right font-medium">
                              £{group.costTotal.toLocaleString()}
                            </td>
                            <td />
                          </tr>
                        </Fragment>
                      ))}
                    </tbody>
                  </table>
                </div>
              )}
            </div>

            <div className="mt-6 flex justify-end">
              <button
                onClick={onClose}
                className="rounded-md border px-4 py-2 text-sm font-medium hover:bg-gray-50"
              >
                Close
              </button>
            </div>
          </DialogPanel>
        </div>
      </Dialog>
    </Transition>
  );
}
