"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 match =
    /^(\d{4})-(\d{2})/.exec(
      String(
        value ?? "",
      ).trim(),
    );

  if (!match) {
    return "";
  }

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

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

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

      const normalized =
        normalizeValue(
          cleaned,
        );

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

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

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

  const normalized =
    normalizeValue(
      value,
    );

  return selected.some(
    (item) =>
      normalizeValue(
        item,
      ) === normalized,
  );
}

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 safeRows =
    Array.isArray(
      rows,
    )
      ? rows
      : [];

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

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

  /*
   * Filter dropdown options
   * only from actual table data
   */
  const filterOptions =
    useMemo<RgcDecisionFilterOptions>(
      () => ({
        status:
          uniqueValues(
            safeRows.map(
              (row) =>
                row.status ||
                "",
            ),
          ),

        primaryAgency:
          uniqueValues(
            safeRows.map(
              (row) =>
                row.primaryAgency ||
                row.ministry ||
                "",
            ),
          ).sort(),

        category:
          uniqueValues(
            safeRows.map(
              (row) =>
                row.category ||
                row.measureCategory ||
                "",
            ),
          ).sort(),

        meetingDate:
          uniqueValues(
            safeRows
              .map(
                (row) =>
                  normalizeMeetingMonth(
                    row.meetingDate ||
                      row.effectiveDate,
                  ),
              )
              .filter(Boolean),
          ).sort(
            (a, b) =>
              b.localeCompare(
                a,
              ),
          ),
      }),
      [safeRows],
    );

  const handleFilterChange =
    (
      key:
        keyof RgcDecisionFilterState,

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

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

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

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

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

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

            return (
              matchesSelected(
                filters.status,
                row.status ||
                  "",
              ) &&
              matchesSelected(
                filters.primaryAgency,
                agency,
              ) &&
              matchesSelected(
                filters.category,
                category,
              ) &&
              (
                filters
                  .meetingDate
                  .length ===
                  0 ||
                filters.meetingDate.includes(
                  date,
                )
              )
            );
          },
        ),
      [
        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
        }
      />

      {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
        }
        options={
          filterOptions
        }
        language={
          rgcLanguage
        }
        viewMode={
          viewMode
        }
        onViewModeChange={
          setViewMode
        }
        onChange={
          handleFilterChange
        }
        onReset={
          handleResetFilters
        }
      />

      <Typography
        sx={{
          mb: 2,

          fontSize: 16,

          fontWeight: 700,

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

      {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>
      ) : (
        <RgcDecisionGrid
          rows={
            filteredRows
          }
          language={
            rgcLanguage
          }
          loading={
            isLoading
          }
        />
      )}
    </Box>
  );
}

export default RgcDecisionScreen;