"use client";

import { useMemo, useState } from "react";

import Box from "@mui/material/Box";
import Typography from "@mui/material/Typography";
import { useTheme } from "@mui/material/styles";

import { useAppLanguage } from "@/components/providers/app-language-provider";
import { usePermissions } from "@/features/auth/hook/use-permissions";
import { APP_PERMISSIONS } from "@/features/auth/permissions";
import {
  useIssueMatrixList,
  useIssueMatrixSummary,
} from "@/features/pswg/issue-matrix/hook/use-issue-matrix";
import { useWgIssuesFilterOptions } from "@/features/pswg/working-group-issues/hook/use-working-group-issues";
import { exportIssueMatrix } from "@/features/pswg/issue-matrix/service/issue-matrix-service";

import {
  defaultIssueMatrixFilters,
  IssueMatrixFilters,
  type IssueMatrixFilterOptions,
  type IssueMatrixFilterState,
} from "./issue-matrix-filters";
import { IssueMatrixHeader } from "./issue-matrix-header";
import { IssueMatrixStatusCards } from "./issue-matrix-status-cards";
import { IssueMatrixTable } from "./issue-matrix-table";
import { normalizeIssueMatrixLanguage } from "./issue-matrix-i18n";

type IssueMatrixScreenProps = {
  // Where a row's "View Detail" link goes. CDC-GPSF passes its own base path
  // ("/cdc-gpsf/issue-matrix") so users stay inside their section.
  detailBasePath?: string;
};

export function IssueMatrixScreen({
  detailBasePath = "/pswg/issue-matrix",
}: IssueMatrixScreenProps) {
  const theme = useTheme();
  const { language } = useAppLanguage();
  const { can } = usePermissions();
  const issueMatrixLanguage = normalizeIssueMatrixLanguage(language);
  const canExportIssueMatrix = can(APP_PERMISSIONS.issueMatrix.export);
  const {
    rows,
    isLoading: isLoadingRows,
    error: rowsError,
  } = useIssueMatrixList();
  const { summary, isLoading: isLoadingSummary } = useIssueMatrixSummary();
  const {
    statuses,
    categories,
    agencies,
    isLoading: isLoadingExportLookups,
    error: exportLookupError,
  } = useWgIssuesFilterOptions();

  const [search, setSearch] = useState("");
  const [isExporting, setIsExporting] = useState(false);
  const [exportError, setExportError] = useState("");
  const [filters, setFilters] = useState<IssueMatrixFilterState>({
    ...defaultIssueMatrixFilters,
  });

  const filterOptions = useMemo<IssueMatrixFilterOptions>(() => {
    const getUniqueOptions = (values: string[], sortDescending = false) => {
      const options = Array.from(
        new Set(values.filter(Boolean).filter((value) => value !== "-")),
      );

      options.sort((firstValue, secondValue) =>
        sortDescending
          ? Number(secondValue) - Number(firstValue)
          : firstValue.localeCompare(secondValue),
      );

      return options;
    };

    return {
      workingGroup: getUniqueOptions(rows.map((row) => row.workingGroup)),
      status: getUniqueOptions(rows.map((row) => row.status)),
      category: getUniqueOptions(rows.map((row) => row.category)),
      primaryAgency: getUniqueOptions(rows.map((row) => row.primaryAgency)),
      year: getUniqueOptions(
        rows.map((row) => row.year),
        true,
      ),
      progressReport: getUniqueOptions(rows.map((row) => row.progressReport)),
      attachment: ["Yes", "No"],
    };
  }, [rows]);

  const primaryAgencyLogos = useMemo(() => {
    const logos: Record<string, string | null> = {};

    for (const row of rows) {
      if (!row.primaryAgency || logos[row.primaryAgency] !== undefined) {
        continue;
      }

      logos[row.primaryAgency] = row.primaryAgencyImage;
    }

    return logos;
  }, [rows]);

  const handleFilterChange = (
    key: keyof IssueMatrixFilterState,
    value: string[],
  ) => {
    setFilters((prev) => ({
      ...prev,
      [key]: value,
    }));
  };

  const handleExport = async () => {
    setExportError("");
    setIsExporting(true);

    try {
      await exportIssueMatrix({
        language: issueMatrixLanguage,
        search,
        selectedWorkingGroups: filters.workingGroup,
        selectedStatuses: filters.status,
        selectedCategories: filters.category,
        selectedPrimaryAgencies: filters.primaryAgency,
        selectedYears: filters.year,
        selectedAttachments: filters.attachment,
        rows,
        statuses,
        categories,
        agencies,
      });
    } catch (error) {
      setExportError(
        error instanceof Error
          ? error.message
          : "Unable to export issue matrix.",
      );
    } finally {
      setIsExporting(false);
    }
  };

  const filteredRows = useMemo(() => {
    const normalizedSearch = search.trim().toLowerCase();

    return rows.filter((row) => {
      const matchesSearch =
        normalizedSearch === "" ||
        [
          row.issue,
          row.category,
          row.issueDescription,
          row.recommendation,
          row.governmentDecision,
          row.primaryAgency,
          row.workingGroup,
          row.sourceOfVerification,
          row.status,
          row.year,
          row.progressReport,
        ]
          .join(" ")
          .toLowerCase()
          .includes(normalizedSearch);

      const matchesWorkingGroup =
        filters.workingGroup.length === 0 ||
        filters.workingGroup.includes(row.workingGroup);

      const matchesStatus =
        filters.status.length === 0 || filters.status.includes(row.status);

      const matchesCategory =
        filters.category.length === 0 ||
        filters.category.includes(row.category);

      const matchesPrimaryAgency =
        filters.primaryAgency.length === 0 ||
        filters.primaryAgency.includes(row.primaryAgency);

      const matchesYear =
        filters.year.length === 0 || filters.year.includes(row.year);

      const matchesProgressReport =
        filters.progressReport.length === 0 ||
        filters.progressReport.includes(row.progressReport);

      const matchesAttachment =
        filters.attachment.length === 0 ||
        (filters.attachment.includes("Yes") && row.hasAttachment) ||
        (filters.attachment.includes("No") && !row.hasAttachment);

      return (
        matchesSearch &&
        matchesWorkingGroup &&
        matchesStatus &&
        matchesCategory &&
        matchesPrimaryAgency &&
        matchesYear &&
        matchesProgressReport &&
        matchesAttachment
      );
    });
  }, [search, filters, rows]);

  return (
    <Box
      sx={{
        minHeight: "calc(100dvh - 64px)",
        width: "100%",
        display: "flex",
        flexDirection: "column",
        bgcolor: theme.palette.background.default,
        color: theme.palette.text.primary,
        px: { xs: 2, md: 3 },
        py: { xs: 2, md: 3 },
      }}
    >
      <Box
        sx={{
          flex: 1,
          minHeight: 0,
          width: "100%",
          display: "flex",
          flexDirection: "column",
        }}
      >
        <IssueMatrixHeader
          search={search}
          canExport={canExportIssueMatrix}
          language={issueMatrixLanguage}
          exportDisabled={
            !canExportIssueMatrix ||
            isLoadingRows ||
            isLoadingExportLookups ||
            Boolean(exportLookupError) ||
            rows.length === 0
          }
          exportLoading={isExporting}
          onExport={handleExport}
          onSearchChange={setSearch}
        />

        {exportError ? (
          <Typography
            sx={{
              mb: 2,
              color: "#f04438",
              fontSize: 13,
              fontWeight: 500,
            }}
          >
            {exportError}
          </Typography>
        ) : null}

        <IssueMatrixFilters
          filters={filters}
          language={issueMatrixLanguage}
          options={filterOptions}
          primaryAgencyLogos={primaryAgencyLogos}
          onChange={handleFilterChange}
        />

        <Box sx={{ mb: 3 }}>
          <IssueMatrixStatusCards
            language={issueMatrixLanguage}
            summary={summary}
          />
        </Box>

        <IssueMatrixTable
          rows={filteredRows}
          language={issueMatrixLanguage}
          loading={isLoadingRows || isLoadingSummary}
          error={rowsError}
          detailBasePath={detailBasePath}
        />
      </Box>
    </Box>
  );
}
