"use client";

import { useState, useMemo } from "react";
import { useQuery } from "@tanstack/react-query";
import { ScenarioSelectorWrapper } from "./scenarioSelectorWrapper";
import { DashboardSummaryCards } from "./DashboardSummaryCards";
import { BreakdownChart } from "./BreakdownChart";
import { EpcQualityCards } from "./EpcQualityCards";
import { ScenarioFinancialDrawer } from "./ScenarioFinancialDrawer";
import { ScenarioMeasuresModal } from "./ScenarioMeasuresModal";

import { SectionDivider } from "@/app/portfolio/[slug]/(portfolio)/reporting/SectionDivider";
import {
  PlaceholderMetricCards,
  CONDITION_PLACEHOLDERS,
  FINANCIAL_PLACEHOLDERS,
} from "@/app/portfolio/[slug]/(portfolio)/reporting/PlaceholderMetricCards";

import type {
  BaselineMetrics,
  PropertyTypeCount,
  ScenarioSummary,
} from "./types";
import { ReportingFunctionalityButtons } from "./ReportingFunctionalityButtons";
import { RecommendationsOptions } from "./RecommendationsOptions";
import SuccessToast from "../../components/SuccessToast";

interface ReportingClientAreaProps {
  baseline: BaselineMetrics;
  propertyTypes: PropertyTypeCount[];
  scenarios: ScenarioSummary[];
  portfolioId: number;
}

// ----------------------------------------
//  Fetcher for scenario API route
// ----------------------------------------
async function fetchScenarioReport({
  portfolioId,
  scenarioId,
  hideNonCompliant,
  useOriginalBaseline,
}: {
  portfolioId: number;
  scenarioId: number | "default";
  hideNonCompliant: boolean;
  useOriginalBaseline: boolean;
}) {
  const params = new URLSearchParams({
    hideNonCompliant: String(hideNonCompliant),
    useOriginalBaseline: String(useOriginalBaseline),
  });

  const path = `/api/portfolio/${portfolioId}/scenario/${scenarioId}/metrics`;

  const res = await fetch(`${path}?${params.toString()}`);

  if (!res.ok) {
    throw new Error("Failed to load scenario report");
  }

  return res.json();
}

async function fetchScenarioMeasures({
  portfolioId,
  scenarioId,
}: {
  portfolioId: number;
  scenarioId: number | "default";
}) {
  const path = `/api/portfolio/${portfolioId}/scenario/${scenarioId}/measures`;

  const res = await fetch(path);

  if (!res.ok) {
    throw new Error("Failed to load measures");
  }

  return res.json();
}

export function ReportingClientArea({
  baseline,
  propertyTypes,
  scenarios,
  portfolioId,
}: ReportingClientAreaProps) {
  const [selectedScenarioId, setSelectedScenarioId] = useState<
    number | "default" | null
  >(null);
  const [measuresOpen, setMeasuresOpen] = useState<boolean>(false);
  const [appliedHideNonCompliant, setAppliedHideNonCompliant] =
    useState<boolean>(false);
  const [appliedUseOriginalBaseline, setAppliedUseOriginalBaseline] =
    useState<boolean>(false);
  const [showToast, setShowToast] = useState(false);

  const drawerOpen = Boolean(selectedScenarioId);

  // ----------------------------------------
  // React Query: fetch scenario metrics
  // ----------------------------------------
  const {
    data: scenarioData,
    isLoading,
    isFetching,
    isError,
  } = useQuery({
    queryKey: [
      "scenario-report",
      portfolioId,
      selectedScenarioId,
      appliedHideNonCompliant,
      appliedUseOriginalBaseline,
    ],
    queryFn: () =>
      fetchScenarioReport({
        portfolioId,
        scenarioId: selectedScenarioId!,
        hideNonCompliant: appliedHideNonCompliant,
        useOriginalBaseline: appliedUseOriginalBaseline,
      }),
    enabled: selectedScenarioId !== null, // only run when scenario selected or default selected
    keepPreviousData: true, // keep showing old data while loading new scenario or applying filter
    refetchOnWindowFocus: false,
  });

  const {
    data: measuresData,
    isLoading: measuresLoading,
    isError: measuresError,
  } = useQuery({
    queryKey: ["scenario-measures", portfolioId, selectedScenarioId],
    queryFn: () =>
      fetchScenarioMeasures({
        portfolioId,
        scenarioId: selectedScenarioId!,
      }),
    enabled: measuresOpen && !!selectedScenarioId,
    keepPreviousData: true,
    refetchOnWindowFocus: false,
  });

  // ----------------------------------------
  // Build overlay for Dashboard Summary cards
  // ----------------------------------------

  const scenarioOverlay = scenarioData
    ? {
        avgSap: {
          baseline: baseline.averages.avg_sap ?? 0,
          scenario: Number(scenarioData.avg_sap),
        },
        avgCarbon: {
          baseline: Number(baseline.averages.avg_carbon ?? 0),
          scenario: Number(scenarioData.avg_carbon),

          baselineTotal: Number(baseline.totals.total_carbon ?? 0),
          scenarioTotal: Number(scenarioData.total_carbon ?? 0),
        },
        avgBills: {
          baseline: baseline.averages.avg_bills ?? 0,
          scenario: scenarioData.avg_bills,
          baselineTotal: baseline.totals.total_bills ?? 0,
          scenarioTotal: scenarioData.total_bills,
        },
        valuation: { baseline: null, scenario: null },
        scenarioEpcBands: scenarioData.scenario_epc_counts,
      }
    : null;

  // ----------------------------------------
  // Scenario specific metrics that appear in the drawer (from API) and cannot be overlayed on baseline
  // ----------------------------------------

  const scenarioSpecific = useMemo(() => {
    if (!scenarioData) return null;

    return {
      constructionCost: scenarioData.construction_cost,
      pcCost: scenarioData.pc_cost,
      contingency: scenarioData.contingency,
      funding: scenarioData.total_funding,
      costPerSap:
        scenarioData.total_sap_uplift && scenarioData.total_sap_uplift > 0
          ? (scenarioData.construction_cost + scenarioData.pc_cost) /
            scenarioData.total_sap_uplift
          : 0,
      costPerCo2:
        scenarioData.construction_cost > 0
          ? (scenarioData.construction_cost + scenarioData.pc_cost) /
            ((baseline.totals.total_carbon ?? 0) - scenarioData.total_carbon)
          : 0,
      netCost: scenarioData.net_cost,
      grossPerUnit: scenarioData.gross_per_unit,
      nUnits: scenarioData.n_units_upgraded,
      totalCarbonSaved:
        (baseline.totals.total_carbon ?? 0) - scenarioData.total_carbon,
      totalBillsSaved:
        (baseline.totals.total_bills ?? 0) - scenarioData.total_bills,
      averageCaribonSaved:
        ((baseline.totals.total_carbon ?? 0) - scenarioData.total_carbon) /
        scenarioData.n_units_upgraded,
      averageBillsSaved:
        ((baseline.totals.total_bills ?? 0) - scenarioData.total_bills) /
        scenarioData.n_units_upgraded,
    };
  }, [scenarioData, baseline]);

  // Baseline stays baseline
  const activeMetrics = baseline;

  const scenarioBusy = !!selectedScenarioId && (isLoading || isFetching);

  return (
    <>
      <div className="flex items-center justify-between gap-4">
        {/* LEFT: Scenario selector */}
        <ScenarioSelectorWrapper
          scenarios={scenarios}
          portfolioId={portfolioId}
          selectedScenarioId={selectedScenarioId}
          setSelectedScenarioId={setSelectedScenarioId}
        />

        {/* RIGHT: Actions (only when scenario selected) */}
        {selectedScenarioId && (
          <div className="flex items-center gap-2">
            {/* Show measures */}
            <button
              onClick={() => setMeasuresOpen(true)}
              disabled={scenarioBusy}
              className={`
        rounded-md px-3 py-2 text-sm font-medium transition
        ${
          scenarioBusy
            ? "bg-gray-200 text-gray-400 cursor-not-allowed"
            : "bg-brandblue text-white hover:bg-hoverblue"
        }
      `}
            >
              {scenarioBusy ? "Loading…" : "Show measures"}
            </button>

            <ReportingFunctionalityButtons
              hideNonCompliant={appliedHideNonCompliant}
              useOriginalBaseline={appliedUseOriginalBaseline}
              disabled={scenarioBusy}
              canFilterNonCompliant={
                selectedScenarioId !== null && selectedScenarioId !== "default"
              }
              onApply={async ({ hideNonCompliant, useOriginalBaseline }) => {
                setAppliedHideNonCompliant(hideNonCompliant);
                setAppliedUseOriginalBaseline(useOriginalBaseline);
              }}
            />

            {/* Download PDF */}
            <button
              onClick={() => {
                window.open(
                  `/portfolio/${portfolioId}/reporting/pdf?scenarioId=${selectedScenarioId}`,
                  "_blank",
                );
              }}
              disabled={scenarioBusy}
              className={`
        rounded-md border px-3 py-2 text-sm font-medium transition
        ${
          scenarioBusy
            ? "border-gray-200 text-gray-400 cursor-not-allowed"
            : "hover:bg-gray-50"
        }
      `}
            >
              Download PDF
            </button>
          </div>
        )}
        { !selectedScenarioId &&
          <RecommendationsOptions
            disabled={scenarioBusy}
            scenarios={scenarios}
            portfolioId={portfolioId}
            onSuccess={() => setShowToast(true)}
          />
        }
      </div>

      {/* LOADING + ERROR STATES */}
      {isLoading && selectedScenarioId && (
        <div className="text-sm text-gray-500 mt-2">Loading scenario…</div>
      )}
      {isError && (
        <div className="text-sm text-red-500 mt-2">
          Could not load scenario data.
        </div>
      )}

      {/* --- RETROFIT SECTION --- */}
      <SectionDivider
        title="Retrofit Summary"
        subtitle="High-level insights on performance, energy, and EPC quality."
      />

      <ScenarioFinancialDrawer
        open={drawerOpen}
        metrics={scenarioSpecific}
        loading={scenarioBusy}
      />

      <div className="grid grid-cols-1 lg:grid-cols-[60%_40%] gap-6 p-2">
        <DashboardSummaryCards
          total={activeMetrics.total}
          totals={activeMetrics.totals}
          averages={activeMetrics.averages}
          estimatedCounts={activeMetrics.estimatedCounts}
          scenarioOverlay={scenarioOverlay}
          loading={scenarioBusy}
        />

        <BreakdownChart
          epcBands={activeMetrics.epcBands}
          ageBands={activeMetrics.ageBands}
          propertyTypes={propertyTypes}
          scenarioEpcBands={scenarioOverlay?.scenarioEpcBands}
        />

        <div className="lg:col-span-2">
          <EpcQualityCards
            estimatedCounts={activeMetrics.estimatedCounts}
            total={activeMetrics.total}
            expiredEpcs={activeMetrics.expiredEpcs}
            likelyDowngrades={activeMetrics.likelyDowngrades}
          />
        </div>
      </div>

      {/* --- CONDITION SECTION --- */}
      <SectionDivider
        title="Condition"
        subtitle="Awaabs Law, decent homes and compliance"
      />
      <PlaceholderMetricCards items={CONDITION_PLACEHOLDERS} />

      {/* --- FINANCIAL SECTION --- */}
      <SectionDivider
        title="Financial Overview"
        subtitle="Total bills, cost exposure, and potential funding pathways."
      />
      <PlaceholderMetricCards items={FINANCIAL_PLACEHOLDERS} />

      <ScenarioMeasuresModal
        isOpen={measuresOpen}
        onClose={() => setMeasuresOpen(false)}
        isLoading={measuresLoading}
        data={measuresData ?? null}
        error={measuresError}
      />

      <SuccessToast
        show={showToast}
        showConfetti={false}
        onClose={() => setShowToast(false)}
        message="Recommendation process triggered"
        subtext="Recommendations might take a few minutes to update"
        timeoutMs={6000}
      />
    </>
  );
}
