"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 {
  normalizeRgcDecisionLanguage,
  rgcDecisionText,
} from "../data/rgc-decision-i18n";

import { useRgcDecisionList } from "../hook/use-rgc-decision";

import {
  RgcDecisionFilters,
  defaultRgcDecisionFilters,
  type RgcDecisionFilterOptions,
  type RgcDecisionFilterState,
  type RgcDecisionViewMode,
} from "./rgc-decision-filters";

import { RgcDecisionGrid } from "./rgc-decision-grid";
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 = [],
    isLoading,
    error,
    reload,
  } =
    useRgcDecisionList();

  const [
    viewMode,
    setViewMode,
  ] =
    useState<RgcDecisionViewMode>(
      "list",
    );

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

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

  /*
   * FILTER OPTIONS
   * ONLY FROM TABLE DATA
   */
  const filterOptions =
    useMemo<RgcDecisionFilterOptions>(
      () => {
        const status =
          uniqueValues(
            safeRows.map(
              (row) =>
                row.status ||
                "",
            ),
          );

        const primaryAgency =
          uniqueValues(
            safeRows.map(
              (row) =>
                row.primaryAgency ||
                row.ministry ||
                "",
            ),
          ).sort(
            (a, b) =>
              a.localeCompare(b),
          );

        const category =
          uniqueValues(
            safeRows.map(
              (row) =>
                row.category ||
                row.measureCategory ||
                "",
            ),
          ).sort(
            (a, b) =>
              a.localeCompare(b),
          );

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

        return {
          status,
          primaryAgency,
          category,
          meetingDate,
        };
      },
      [safeRows],
    );

  const handleFilterChange =
    (
      key:
        keyof RgcDecisionFilterState,

      values: string[],
    ) => {
      setFilters(
        (current) => ({
          ...current,

          [key]:
            values,
        }),
      );
    };

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

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

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

          const rowStatus =
            row.status ||
            "";

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

          const matchesStatus =
            matchesSelected(
              filters.status ??
                [],

              rowStatus,
            );

          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,
        },
      }}
    >
      {/* HEADER */}
      <RgcDecisionHeader
        language={
          rgcLanguage
        }
        onReset={
          handleResetFilters
        }
      />

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

      {/* FILTERS + VIEW */}
      <RgcDecisionFilters
        filters={
          filters
        }
        options={
          filterOptions
        }
        language={
          rgcLanguage
        }
        viewMode={
          viewMode
        }
        onViewModeChange={
          setViewMode
        }
        onChange={
          handleFilterChange
        }
      />

      {/* LIST TITLE */}
      <Typography
        sx={{
          mb: 2,

          fontSize: 16,

          fontWeight: 700,

          color:
            theme.palette.text
              .primary,
        }}
      >
        {viewMode ===
        "grid"
          ? rgcLanguage ===
            "kh"
            ? "សេចក្តីសម្រេចរបស់រាជរដ្ឋាភិបាល"
            : "RGC Decision"
          : text.listTitle}
      </Typography>

      {/* LIST VIEW */}
      {viewMode ===
      "list" ? (
        <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>
      ) : (
        /* GRID VIEW */
        <RgcDecisionGrid
          rows={
            filteredRows
          }
          language={
            rgcLanguage
          }
          loading={
            isLoading
          }
        />
      )}
    </Box>
  );
}

export default RgcDecisionScreen;