"use client";

import {
  useMemo,
  useState,
} from "react";

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

import { useAppLanguage } from "@/components/providers/app-language-provider";

import { RGC_DECISION_STATUS_OPTIONS } from "../data/rgc-decision-data";
import {
  normalizeRgcDecisionLanguage,
  rgcDecisionText,
} from "../data/rgc-decision-i18n";
import { useRgcDecisionList } from "../hook/use-rgc-decision";

import { CreateRgcDecisionDialog } from "./create-rgc-decision-dialog";
import {
  RgcDecisionFilters,
  defaultRgcDecisionFilters,
  type RgcDecisionFilterOptions,
  type RgcDecisionFilterState,
} from "./rgc-decision-filters";
import { RgcDecisionHeader } from "./rgc-decision-header";
import { RgcDecisionTable } from "./rgc-decision-table";

function normalizeValue(
  value: string | null | undefined,
): string {
  return String(value ?? "")
    .trim()
    .replace(/\s+/g, " ")
    .toLowerCase();
}

function normalizeMeetingMonth(
  value: string | null | undefined,
): string {
  const text = String(
    value ?? "",
  ).trim();

  const match =
    /^(\d{4})-(\d{2})/.exec(
      text,
    );

  if (!match) {
    return "";
  }

  return `${match[1]}-${match[2]}`;
}

function uniqueValues(
  values: string[],
): string[] {
  const result =
    new Map<string, string>();

  values.forEach((value) => {
    const cleaned = String(
      value ?? "",
    )
      .trim()
      .replace(/\s+/g, " ");

    const normalized =
      normalizeValue(cleaned);

    if (
      normalized &&
      !result.has(normalized)
    ) {
      result.set(
        normalized,
        cleaned,
      );
    }
  });

  return Array.from(
    result.values(),
  );
}

function matchesSelected(
  selectedValues: string[],
  rowValue: string,
): boolean {
  if (
    selectedValues.length === 0
  ) {
    return true;
  }

  const normalizedRow =
    normalizeValue(rowValue);

  return selectedValues.some(
    (selectedValue) =>
      normalizeValue(
        selectedValue,
      ) === normalizedRow,
  );
}

export function RgcDecisionScreen() {
  const theme = useTheme();

  const { language } =
    useAppLanguage();

  const rgcLanguage =
    normalizeRgcDecisionLanguage(
      language,
    );

  const text =
    rgcDecisionText[
      rgcLanguage
    ] ?? rgcDecisionText.en;

  const {
    rows = [],
    plenaries = [],
    ministries = [],
    categories = [],
    isLoading,
    error,
    reload,
  } = useRgcDecisionList();

  const [
    createDialogOpen,
    setCreateDialogOpen,
  ] = useState(false);

  const [
    filters,
    setFilters,
  ] =
    useState<RgcDecisionFilterState>(
      {
        ...defaultRgcDecisionFilters,
      },
    );

  const safeRows =
    Array.isArray(rows)
      ? rows
      : [];

  const safePlenaries =
    Array.isArray(plenaries)
      ? plenaries
      : [];

  const safeMinistries =
    Array.isArray(ministries)
      ? ministries
      : [];

  const safeCategories =
    Array.isArray(categories)
      ? categories
      : [];

  const filterOptions =
    useMemo<RgcDecisionFilterOptions>(
      () => ({
        status: [
          ...RGC_DECISION_STATUS_OPTIONS,
        ],

        primaryAgency:
          safeMinistries.length > 0
            ? safeMinistries.map(
                (item) =>
                  item.label,
              )
            : uniqueValues(
                safeRows.map(
                  (row) =>
                    row.primaryAgency ||
                    row.ministry ||
                    "",
                ),
              ),

        category:
          safeCategories.length > 0
            ? safeCategories.map(
                (item) =>
                  item.label,
              )
            : uniqueValues(
                safeRows.map(
                  (row) =>
                    row.category ||
                    row.measureCategory ||
                    "",
                ),
              ),

        meetingDate: uniqueValues(
          safeRows
            .map((row) =>
              normalizeMeetingMonth(
                row.meetingDate ||
                  row.effectiveDate,
              ),
            )
            .filter(
              (
                value,
              ): value is string =>
                Boolean(value),
            ),
        ).sort((first, second) =>
          second.localeCompare(
            first,
          ),
        ),
      }),
      [
        safeRows,
        safeMinistries,
        safeCategories,
      ],
    );

  const handleFilterChange = (
    key:
      keyof RgcDecisionFilterState,
    values: string[],
  ) => {
    setFilters((current) => ({
      ...current,
      [key]: values,
    }));
  };

  const handleResetFilters =
    () => {
      setFilters({
        ...defaultRgcDecisionFilters,
      });
    };

  const filteredRows =
    useMemo(() => {
      return safeRows.filter(
        (row) => {
          const rowAgency =
            row.primaryAgency ||
            row.ministry ||
            "";

          const rowCategory =
            row.category ||
            row.measureCategory ||
            "";

          const rowMeetingDate =
            normalizeMeetingMonth(
              row.meetingDate ||
                row.effectiveDate,
            );

          const matchesStatus =
            matchesSelected(
              filters.status ?? [],
              row.status || "",
            );

          const matchesAgency =
            matchesSelected(
              filters.primaryAgency ??
                [],
              rowAgency,
            );

          const matchesCategory =
            matchesSelected(
              filters.category ?? [],
              rowCategory,
            );

          const selectedDates =
            filters.meetingDate ?? [];

          const matchesMeetingDate =
            selectedDates.length === 0 ||
            selectedDates.includes(
              rowMeetingDate,
            );

          return (
            matchesStatus &&
            matchesAgency &&
            matchesCategory &&
            matchesMeetingDate
          );
        },
      );
    }, [filters, safeRows]);

  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,
          },
        }}
      >
        <RgcDecisionHeader
          language={rgcLanguage}
          onCreateRgc={() => {
            setCreateDialogOpen(
              true,
            );
          }}
        />

        {error ? (
          <Alert
            severity="error"
            sx={{
              mb: 2,
            }}
            action={
              <Button
                color="inherit"
                size="small"
                onClick={() => {
                  void reload();
                }}
              >
                {text.reload}
              </Button>
            }
          >
            {error}
          </Alert>
        ) : null}

        <RgcDecisionFilters
          filters={filters}
          language={rgcLanguage}
          options={filterOptions}
          onChange={
            handleFilterChange
          }
          onReset={
            handleResetFilters
          }
        />

        <Typography
          sx={{
            mb: 3,

            fontSize: 16,
            fontWeight: 700,

            color:
              theme.palette.text
                .primary,
          }}
        >
          {text.listTitle}
        </Typography>

        <Paper
          elevation={0}
          sx={{
            flex: 1,
            minHeight: 428,

            display: "flex",
            flexDirection: "column",

            overflow: "hidden",

            borderRadius: "12px",

            border: `1px solid ${
              theme.palette.mode ===
              "dark"
                ? "rgba(255,255,255,0.12)"
                : "#E9EAEB"
            }`,

            bgcolor:
              theme.palette.background
                .paper,
          }}
        >
          <RgcDecisionTable
            rows={filteredRows}
            language={rgcLanguage}
            loading={isLoading}
            error={error}
          />
        </Paper>
      </Box>

      <CreateRgcDecisionDialog
        open={createDialogOpen}
        plenaries={safePlenaries}
        ministries={safeMinistries}
        categories={safeCategories}
        onClose={() => {
          setCreateDialogOpen(
            false,
          );
        }}
        onCreated={async () => {
          await reload();

          setCreateDialogOpen(
            false,
          );
        }}
      />
    </>
  );
}

export default RgcDecisionScreen;