"use client";

import { type ReactNode, useState } from "react";
import { Alert, Box, Stack, Typography } from "@mui/material";
import {
  DashboardExportProvider,
  DashboardChartExport,
} from "@/components/dashboard/dashboard-export-provider";
import {
  buildSummaryTable,
  buildStatusTable,
  buildAgenciesTable,
  buildWorkingGroupsTable,
  buildCategoriesTable,
  localizeExportTable,
} from "../dashboard/cdc-gpsf-dashboard-export";
import { CdcGpsfDashboardActions } from "../dashboard/components/cdc-gpsf-dashboard-actions";
import { formatDate } from "@/lib/date-utils";
import {
  FilterPanelGrouped,
  type FilterPanelOptionsField,
} from "@/components/ui/filter-panel";
import { DashboardPageContainer } from "@/features/ministry/dashboard/components/dashboard-page-container";
import { DashboardResetButton } from "@/features/ministry/dashboard/components/dashboard-reset-button";
import { IssueMatrixStatusCards } from "@/features/pswg/issue-matrix/components/issue-matrix-status-cards";
import { CdcGpsfDashboardHeader } from "../dashboard/components/cdc-gpsf-dashboard-header";
import { useAppLanguage } from "@/components/providers/app-language-provider";
import { useQuery } from "@tanstack/react-query";
import { baseAPI } from "@/lib/api";
import type { DraftDashboard } from "../progress-report/components/draft-dashboard/draft-dashboard-service";
import { formatNumber } from "@/lib/number-utils";
import { AgencyStatusCard } from "@/features/ministry/dashboard/components/charts/agency-status-card";
import { OverallStatusCard } from "@/features/ministry/dashboard/components/charts/overall-status-card";
import { CategoryIssuesCard } from "@/features/ministry/dashboard/components/charts/category-issues-card";
import { WorkingGroupStatusCard } from "@/features/ministry/dashboard/components/charts/dashboard-status-card";
import { toPlenarySummary } from "../plenary/dashboard/service/live-plenary-service";
import {
  DashboardTranslationProvider,
  useDashboardTranslations,
} from "../dashboard/dashboard-translation-provider";
import {
  defaultCdcGpsfDashboardFilters,
  translateDashboardChartLabel,
} from "../dashboard/cdc-gpsf-dashboard-data";
import {
  filterLinkedSnapshot,
  type DashboardSummary,
} from "../dashboard/service/cdc-gpsf-dashboard-service";
import {
  mapAgenciesToAgencyRows,
  hasAgencyChartData,
  mapWorkingGroupsToRows,
  mapCategoriesToRows,
  mapCardsToDonut,
  mapCardsToStatusCounts,
} from "../dashboard/cdc-gpsf-dashboard-mappers";
import { combineSummaries } from "./combine-summaries";

export function OverviewScreen() {
  return (
    <DashboardTranslationProvider>
      <Overview />
    </DashboardTranslationProvider>
  );
}

function Overview() {
  const { language } = useAppLanguage();
  const kh = language === "kh";
  const t = useDashboardTranslations();
  const [scope, setScope] = useState("all");
  const [year, setYear] = useState("");
  type Board = { incomplete: boolean; dashboard: DraftDashboard | null };
  type History = { years: number[]; wg: Board; plenary: Board };
  const query = useQuery({
    queryKey: ["live-dashboard", "overview-history", year],
    queryFn: async () => {
      const response = (await baseAPI(
        "/dashboards/overview/history" + (year ? "?year=" + year : ""),
      )) as { data: History };
      return response.data;
    },
  });
  const wg = scope !== "plenary" ? query.data?.wg : undefined;
  const plenary = scope !== "wg" ? query.data?.plenary : undefined;
  const wgLabel = kh ? "បញ្ហាក្រុមការងារ" : "WG Issues";
  const plenaryLabel = kh ? "សេចក្តីសម្រេចវេទិកា" : "Plenary RGC Decisions";

  const sourceFields: FilterPanelOptionsField[] = [
    {
      key: "year",
      label: kh ? "ឆ្នាំរបាយការណ៍" : "Reporting year",
      multiple: false,
      value: year ? [year] : [],
      options: [
        { value: "all", label: kh ? "គ្រប់ឆ្នាំ" : "All years" },
        ...(query.data?.years ?? []).map((n) => ({
          value: String(n),
          label: formatNumber(n, language),
        })),
      ],
    },
    {
      key: "scope",
      label: kh ? "ប្រភេទ" : "Record type",
      multiple: false,
      value: scope === "all" ? [] : [scope],
      options: [
        { value: "all", label: kh ? "ទាំងអស់" : "All records" },
        { value: "wg", label: wgLabel },
        { value: "plenary", label: plenaryLabel },
      ],
    },
  ];
  const notice = query.isLoading ? (
    <Typography role="status">{kh ? "កំពុងផ្ទុក…" : "Loading…"}</Typography>
  ) : query.isError ? (
    <Alert severity="error">{t.loadFailed}</Alert>
  ) : wg?.incomplete || plenary?.incomplete ? (
    <Alert severity="info">
      {kh
        ? "មិនអាចរាប់ទិន្នន័យដោយមិនស្ទួនបានទេ ព្រោះការផ្សាយចាស់ខ្វះលេខសម្គាល់។ សូមជ្រើសរើសឆ្នាំផ្សេង។"
        : "An older publication is missing record IDs. A unique total is unavailable for this selection. Try a single year or record type."}
    </Alert>
  ) : !wg?.dashboard && !plenary?.dashboard ? (
    <Alert severity="info">
      {kh
        ? "មិនមានទិន្នន័យដែលបានផ្សាយទេ។"
        : "No published data for this selection."}
    </Alert>
  ) : null;
  const generatedAt = [
    wg?.dashboard?.generatedAt,
    plenary?.dashboard?.generatedAt,
  ]
    .filter((v): v is string => !!v)
    .sort()
    .at(-1);
  return (
    <OverviewCharts
      key={[scope, year, generatedAt].join(":")}
      sourceFields={sourceFields}
      notice={notice}
      generatedAt={generatedAt}
      onSourceChange={(key, value) =>
        key === "scope"
          ? setScope(value || "all")
          : setYear(value === "all" ? "" : value)
      }
      onResetSource={() => {
        setScope("all");
        setYear("");
      }}
      wg={wg?.dashboard ? toPlenarySummary(wg.dashboard) : undefined}
      plenary={
        plenary?.dashboard ? toPlenarySummary(plenary.dashboard) : undefined
      }
    />
  );
}

type Props = {
  wg?: DashboardSummary;
  plenary?: DashboardSummary;
  generatedAt?: string;
  notice: ReactNode;
  sourceFields: FilterPanelOptionsField[];
  onSourceChange: (key: string, value: string) => void;
  onResetSource: () => void;
};
function OverviewCharts({
  wg,
  plenary,
  generatedAt,
  notice,
  sourceFields,
  onSourceChange,
  onResetSource,
}: Props) {
  const { language } = useAppLanguage();
  const kh = language === "kh";
  const t = useDashboardTranslations();
  const number = (n: number) => formatNumber(n, language);
  const [selection, setSelection] = useState({
    agency: "",
    workingGroup: "",
    category: "",
    status: "",
  });
  const canFilter =
    (!wg || wg.crossFilterData?.version === 1) &&
    (!plenary || plenary.crossFilterData?.version === 2);
  const filtered = (snapshot?: DashboardSummary) => {
    if (!snapshot || !canFilter || !Object.values(selection).some(Boolean))
      return snapshot;
    const list = (value: string) => (value ? [value] : []);
    return filterLinkedSnapshot(
      snapshot,
      {
        ...defaultCdcGpsfDashboardFilters,
        agency: list(selection.agency),
        workingGroup: list(selection.workingGroup),
        category: list(selection.category),
      },
      list(selection.status),
    );
  };
  const wgResult = filtered(wg);
  const plenaryResult = filtered(plenary);
  const available = combineSummaries(
    [wg, plenary].filter((s) => s !== undefined),
  );
  const result = combineSummaries(
    [wgResult, plenaryResult].filter((s) => s !== undefined),
  );
  const statusLabels = {
    solved: t.solved,
    inProgress: t.inProgress,
    notAddressed: t.notAddressed,
  };
  const totalLabel = kh ? "ចំនួនទិន្នន័យសរុប" : "Total records";
  const workingGroupRows = mapWorkingGroupsToRows(
    result.byWorkingGroup.filter((group) => group.total > 0),
    language,
    true,
  );
  const choices = {
    agency: available.byPrimaryAgency
      .filter((a) => a.total > 0)
      .map((a) => [String(a.agencyId), a.agencyName]),
    workingGroup: mapWorkingGroupsToRows(
      available.byWorkingGroup.filter((g) => g.total > 0),
      language,
      true,
    ).map((g) => [String(g.ids?.[0]), g.label]),
    category: mapCategoriesToRows(
      available.byCategory.filter((c) => c.count > 0),
      language,
    ).map((c) => [String(c.ids?.[0]), c.label]),
    status: available.statusBreakdown
      .filter((s) => s.count > 0)
      .map((s) => [s.code, translateDashboardChartLabel(s.name, t)]),
  };
  const labels = {
    agency: t.primaryAgency,
    workingGroup: t.workingGroupChart,
    category: t.categoryOfIssues,
    status: t.status,
  };
  function toggle(key: keyof typeof selection, value = "") {
    setSelection((current) => ({
      ...current,
      [key]: current[key] === value ? "" : value,
    }));
  }
  const resetSelection = () =>
    setSelection({ agency: "", workingGroup: "", category: "", status: "" });
  const exportLabels: Record<string, string> = {
    "Total Issues": totalLabel,
    Solved: t.solved,
    "In Progress": t.inProgress,
    "Not Addressed": t.notAddressed,
    "Total Primary Agencies": t.totalPrimaryAgencies,
    "Working Group": t.workingGroupChart,
    Category: t.categoryOfIssues,
  };
  const tables = Object.fromEntries(
    Object.entries({
      summary: buildSummaryTable(result.cards),
      status: buildStatusTable(result.cards),
      agencies: buildAgenciesTable(
        mapAgenciesToAgencyRows(result.byPrimaryAgency).filter(
          hasAgencyChartData,
        ),
      ),
      groups: buildWorkingGroupsTable(workingGroupRows),
      categories: buildCategoriesTable(
        mapCategoriesToRows(
          result.byCategory.filter((c) => c.count > 0),
          language,
        ),
      ),
    }).map(([key, table]) => [key, [localizeExportTable(table, exportLabels)]]),
  );
  function resetAll() {
    resetSelection();
    onResetSource();
  }
  return (
    <DashboardPageContainer>
      <DashboardExportProvider
        name="gpsf-overview"
        tables={tables}
        disabled={Boolean(notice)}
      >
        <Stack sx={{ gap: 3 }}>
          <CdcGpsfDashboardHeader
            title={kh ? "ទិដ្ឋភាពទូទៅ G-PSF" : "G-PSF Overview"}
            subtitle=""
            actions={
              <CdcGpsfDashboardActions
                readOnly
                updatedLabel={
                  <Typography sx={{ fontSize: 11, color: "text.secondary" }}>
                    <strong>{t.lastUpdated}:</strong>{" "}
                    {formatDate(generatedAt, language, "dd MMMM yyyy, HH:mm")}
                  </Typography>
                }
              />
            }
          />

          <Stack direction="row" sx={{ gap: 2, alignItems: "center" }}>
            <FilterPanelGrouped
              labels={t}
              fields={[
                ...sourceFields,
                ...(canFilter && !notice
                  ? (Object.keys(choices) as (keyof typeof choices)[]).map(
                      (key) => ({
                        key,
                        label: labels[key],
                        multiple: false,
                        options: choices[key].map(([value, label]) => ({
                          value,
                          label,
                        })),
                        value: selection[key] ? [selection[key]] : [],
                      }),
                    )
                  : []),
              ]}
              onChange={(key, values) =>
                key === "scope" || key === "year"
                  ? onSourceChange(key, values[0] ?? "")
                  : setSelection((current) => ({
                      ...current,
                      [key]: values[0] ?? "",
                    }))
              }
              onClearAll={resetAll}
            />
            <Box sx={{ flex: 1 }} />
            <DashboardResetButton label={t.reset} onClick={resetAll} />
          </Stack>
          {notice ?? (
            <>
              {!canFilter && (
                <Alert severity="info">
                  {kh
                    ? "របាយការណ៍នេះមិនមានទិន្នន័យសម្រាប់តម្រងទេ។"
                    : "This snapshot has totals but does not support linked filters."}
                </Alert>
              )}
              <IssueMatrixStatusCards
                language={kh ? "kh" : "en"}
                summary={result.cards}
                labels={{ ...t, totalIssues: totalLabel }}
              />
              <Box
                sx={{
                  display: "grid",
                  gap: 2.75,
                  gridTemplateColumns: {
                    xs: "minmax(0,1fr)",
                    md: "minmax(0, min(43%, 486px)) minmax(0, 1fr)",
                  },
                }}
              >
                <DashboardChartExport name="status">
                  <OverallStatusCard
                    title={t.overallStatus}
                    centerLabel={totalLabel}
                    centerValue={number(result.cards.totalIssues)}
                    data={mapCardsToDonut(result.cards).map((d) => ({
                      ...d,
                      label: translateDashboardChartLabel(d.label, t),
                    }))}
                    counts={mapCardsToStatusCounts(result.cards).map((d) => ({
                      ...d,
                      label: d.code
                        ? translateDashboardChartLabel(d.label, t)
                        : totalLabel,
                      count: number(Number(d.count)),
                    }))}
                    onSelectStatus={
                      canFilter ? (code) => toggle("status", code) : undefined
                    }
                  />
                </DashboardChartExport>
                <DashboardChartExport name="agencies">
                  <AgencyStatusCard
                    valueFontSize={11}
                    title={t.primaryAgencies}
                    statusLabels={statusLabels}
                    formatNumber={number}
                    emptyLabel={kh ? "មិនមានទិន្នន័យ" : "No data"}
                    rows={mapAgenciesToAgencyRows(
                      result.byPrimaryAgency,
                    ).filter(hasAgencyChartData)}
                    onSelect={
                      canFilter
                        ? (row) => toggle("agency", String(row.ids?.[0]))
                        : undefined
                    }
                  />
                </DashboardChartExport>
              </Box>
              <Box
                sx={{
                  display: "grid",
                  gap: 2.75,
                  gridTemplateColumns: {
                    xs: "minmax(0,1fr)",
                    md: "repeat(2,minmax(0,1fr))",
                  },
                }}
              >
                <DashboardChartExport name="groups">
                  <WorkingGroupStatusCard
                    showBreakdown
                    showTracks={false}
                    title={t.workingGroupChart}
                    statusLabels={statusLabels}
                    formatNumber={number}
                    rows={workingGroupRows}
                    onSelect={
                      canFilter
                        ? (row) => toggle("workingGroup", String(row.ids?.[0]))
                        : undefined
                    }
                  />
                </DashboardChartExport>
                <DashboardChartExport name="categories">
                  <CategoryIssuesCard
                    barColor="#1D69B4"
                    valueColor="#ffffff"
                    title={t.categoryOfIssues}
                    formatNumber={number}
                    moreLabel={t.viewAll}
                    lessLabel={t.viewLess}
                    rows={mapCategoriesToRows(
                      result.byCategory.filter((c) => c.count > 0),
                      language,
                    )}
                    onSelect={
                      canFilter
                        ? (row) => toggle("category", String(row.ids?.[0]))
                        : undefined
                    }
                  />
                </DashboardChartExport>
              </Box>
            </>
          )}
        </Stack>
      </DashboardExportProvider>
    </DashboardPageContainer>
  );
}
