"use client";

import { useEffect, useMemo, useState, type ReactNode } from "react";

import Box from "@mui/material/Box";
import ButtonBase from "@mui/material/ButtonBase";
import CircularProgress from "@mui/material/CircularProgress";
import Menu from "@mui/material/Menu";
import MenuItem from "@mui/material/MenuItem";
import Paper from "@mui/material/Paper";
import Typography from "@mui/material/Typography";
import { alpha, useTheme } from "@mui/material/styles";
import type { GridPaginationModel } from "@mui/x-data-grid";

import type { CdcGpsfMeetingRequestRow } from "@/features/cdc-gpsf/meeting-requests/cdc-gpsf-meeting-request-data";
import type { CdcGpsfMeetingRequestUiLang } from "@/features/cdc-gpsf/meeting-requests/cdc-gpsf-meeting-request-i18n";
import {
  cdcGpsfMeetingRequestI18n,
  getCdcGpsfMeetingRequestFont,
} from "@/features/cdc-gpsf/meeting-requests/cdc-gpsf-meeting-request-i18n";
import { useCdcGpsfMeetingRequests } from "@/features/cdc-gpsf/meeting-requests/hook/use-cdc-gpsf-meeting-requests";

import {
  AgencyCell,
  MeetingRequestCell,
  StatusBadge,
  ViewDetailIcon,
} from "../table/cdc-gpsf-meeting-requests-table-cells";
import {
  buildMeetingRequestRows,
  type CdcGpsfMeetingRequestRowWithApi,
} from "../table/cdc-gpsf-meeting-requests-row-utils";
import {
  CDC_GPSF_MEETING_REQUESTS_GRID_PAGE_SIZE,
} from "../table/cdc-gpsf-meeting-requests-table-config";
import { CdcGpsfMeetingRequestsTableFooter } from "../table/cdc-gpsf-meeting-requests-table-footer";

type CdcGpsfMeetingRequestsGridProps = {
  language?: CdcGpsfMeetingRequestUiLang;
  refreshKey?: number;
  workingGroupFilter?: string[];
  governmentAgencyFilter?: string[];
  statusFilter?: string[];
  meetingDateFilter?: string[];
  onView?: (row: CdcGpsfMeetingRequestRow) => void;
};

function GridMetaItem({
  label,
  children,
}: {
  label: string;
  children: ReactNode;
}) {
  const theme = useTheme();
  const isDark = theme.palette.mode === "dark";

  return (
    <Box sx={{ minWidth: 0 }}>
      <Typography
        sx={{
          color: isDark ? alpha("#ffffff", 0.6) : "#717680",
          fontSize: 12,
          fontWeight: 500,
          mb: 0.75,
        }}
      >
        {label}
      </Typography>
      {children}
    </Box>
  );
}

function GridCardMenu({
  row,
  language,
  onView,
}: {
  row: CdcGpsfMeetingRequestRowWithApi;
  language: CdcGpsfMeetingRequestUiLang;
  onView?: (row: CdcGpsfMeetingRequestRow) => void;
}) {
  const theme = useTheme();
  const isDark = theme.palette.mode === "dark";
  const t = cdcGpsfMeetingRequestI18n(language);

  const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);
  const open = Boolean(anchorEl);

  return (
    <Box onClick={(event) => event.stopPropagation()}>
      <ButtonBase
        aria-label="Open meeting request actions"
        onClick={(event) => {
          event.stopPropagation();
          setAnchorEl(event.currentTarget);
        }}
        sx={{
          width: 30,
          height: 30,
          borderRadius: "6px",
          color: isDark ? alpha("#ffffff", 0.6) : "#98a2b3",
          display: "grid",
          placeItems: "center",
          "&:hover": {
            bgcolor: isDark ? alpha("#ffffff", 0.08) : "#f5f5f5",
            color: isDark ? "#ffffff" : "#667085",
          },
        }}
      >
        <Box component="svg" width={18} height={18} viewBox="0 0 20 20" fill="none">
          <path
            d="M10 5.25C10.6904 5.25 11.25 4.69036 11.25 4C11.25 3.30964 10.6904 2.75 10 2.75C9.30964 2.75 8.75 3.30964 8.75 4C8.75 4.69036 9.30964 5.25 10 5.25Z"
            fill="currentColor"
          />
          <path
            d="M10 11.25C10.6904 11.25 11.25 10.6904 11.25 10C11.25 9.30964 10.6904 8.75 10 8.75C9.30964 8.75 8.75 9.30964 8.75 10C8.75 10.6904 9.30964 11.25 10 11.25Z"
            fill="currentColor"
          />
          <path
            d="M10 17.25C10.6904 17.25 11.25 16.6904 11.25 16C11.25 15.3096 10.6904 14.75 10 14.75C9.30964 14.75 8.75 15.3096 8.75 16C8.75 16.6904 9.30964 17.25 10 17.25Z"
            fill="currentColor"
          />
        </Box>
      </ButtonBase>

      <Menu
        anchorEl={anchorEl}
        open={open}
        onClose={() => setAnchorEl(null)}
        anchorOrigin={{ vertical: "bottom", horizontal: "right" }}
        transformOrigin={{ vertical: "top", horizontal: "right" }}
        slotProps={{
          paper: {
            sx: {
              mt: 0.5,
              width: 172,
              borderRadius: "8px",
              border: `1px solid ${
                isDark ? alpha("#ffffff", 0.12) : "#e9eaeb"
              }`,
              backgroundColor: isDark ? "#101828" : "#ffffff",
              boxShadow: "0px 12px 30px rgba(16, 24, 40, 0.16)",
              overflow: "hidden",
            },
          },
        }}
      >
        <MenuItem
          onClick={(event) => {
            event.stopPropagation();
            setAnchorEl(null);
            onView?.(row);
          }}
          sx={{
            gap: 1.25,
            minHeight: 36,
            fontSize: 13,
            color: isDark ? alpha("#ffffff", 0.86) : "#344054",
            fontFamily: getCdcGpsfMeetingRequestFont(language),
          }}
        >
          <ViewDetailIcon size={18} />
          {t.viewDetail}
        </MenuItem>
      </Menu>
    </Box>
  );
}

function GridCard({
  row,
  language,
  onView,
}: {
  row: CdcGpsfMeetingRequestRowWithApi;
  language: CdcGpsfMeetingRequestUiLang;
  onView?: (row: CdcGpsfMeetingRequestRow) => void;
}) {
  const theme = useTheme();
  const isDark = theme.palette.mode === "dark";
  const t = cdcGpsfMeetingRequestI18n(language);

  return (
    <Paper
      elevation={0}
      sx={{
        borderRadius: "12px",
        border: `1px solid ${isDark ? alpha("#ffffff", 0.1) : "#f5f5f5"}`,
        bgcolor: isDark ? "#101828" : "#ffffff",
        px: { xs: 2, md: 2.5 },
        py: { xs: 2, md: 2.25 },
      }}
    >
      <Box
        sx={{
          display: "flex",
          alignItems: "flex-start",
          justifyContent: "space-between",
          gap: 2,
        }}
      >
        <Typography
          sx={{
            color: isDark ? "#ffffff" : "#252b37",
            fontSize: 15,
            fontWeight: 600,
            lineHeight: 1.4,
            fontFamily: getCdcGpsfMeetingRequestFont(language),
          }}
        >
          {row.workingGroup}
        </Typography>

        <GridCardMenu row={row} language={language} onView={onView} />
      </Box>

      <Box
        sx={{
          mt: 2.25,
          display: "grid",
          gridTemplateColumns: {
            xs: "1fr",
            md: "repeat(3, minmax(0, 1fr))",
          },
          columnGap: { xs: 2, md: 4 },
          rowGap: 2.25,
          alignItems: "start",
        }}
      >
        <GridMetaItem label={t.meetingTitle}>
          <Typography
            sx={{
              color: isDark ? "#ffffff" : "#252b37",
              fontSize: 12,
              fontWeight: 500,
              lineHeight: 1.5,
              fontFamily: getCdcGpsfMeetingRequestFont(language),
            }}
          >
            {row.title || "-"}
          </Typography>
        </GridMetaItem>

        <GridMetaItem label={t.meetingDate}>
          <Typography
            sx={{
              color: isDark ? "#ffffff" : "#252b37",
              fontSize: 12,
              fontWeight: 500,
            }}
          >
            {row.meetingDate}
          </Typography>
        </GridMetaItem>

        <GridMetaItem label={t.issuesCount}>
          <Typography
            sx={{
              color: isDark ? "#ffffff" : "#252b37",
              fontSize: 12,
              fontWeight: 500,
            }}
          >
            {row.issuesCount}
          </Typography>
        </GridMetaItem>

        <GridMetaItem label={t.governmentAgency}>
          <AgencyCell
            agency={row.governmentAgency}
            logo={row.governmentAgencyLogo}
            logoSize={24}
            wrap
          />
        </GridMetaItem>

        <GridMetaItem label={t.meetingStatus}>
          <StatusBadge status={row.meetingStatus} language={language} />
        </GridMetaItem>

        <GridMetaItem label={t.meetingRequest}>
          <MeetingRequestCell label={row.meetingRequest} showFullLabel />
        </GridMetaItem>

        <Box
          sx={{
            minWidth: 0,
            gridColumn: { xs: "1", md: "1 / -1" },
          }}
        >
          <GridMetaItem label={t.meetingDescription}>
            <Typography
              sx={{
                color: isDark ? alpha("#ffffff", 0.86) : "#252b37",
                fontSize: 12,
                fontWeight: 400,
                lineHeight: 1.5,
                whiteSpace: "normal",
                wordBreak: "break-word",
                fontFamily: getCdcGpsfMeetingRequestFont(language),
              }}
            >
              {row.meetingDescription}
            </Typography>
          </GridMetaItem>
        </Box>
      </Box>
    </Paper>
  );
}

export function CdcGpsfMeetingRequestsGrid({
  language = "km",
  refreshKey = 0,
  workingGroupFilter = [],
  governmentAgencyFilter = [],
  statusFilter = [],
  meetingDateFilter = [],
  onView,
}: CdcGpsfMeetingRequestsGridProps) {
  const theme = useTheme();
  const isDark = theme.palette.mode === "dark";

  const {
    data,
    workingGroups,
    loading,
    loadingWorkingGroups,
    error,
    fetchMeetingRequests,
    fetchWorkingGroups,
  } = useCdcGpsfMeetingRequests();

  useEffect(() => {
    fetchMeetingRequests();
    fetchWorkingGroups();
  }, [refreshKey, fetchMeetingRequests, fetchWorkingGroups]);

  const rows = useMemo(
    () =>
      buildMeetingRequestRows(data, workingGroups, {
        workingGroupFilter,
        governmentAgencyFilter,
        statusFilter,
        meetingDateFilter,
      }),
    [
      data,
      workingGroups,
      workingGroupFilter,
      governmentAgencyFilter,
      statusFilter,
      meetingDateFilter,
    ],
  );

  const [paginationModel, setPaginationModel] = useState<GridPaginationModel>({
    page: 0,
    pageSize: CDC_GPSF_MEETING_REQUESTS_GRID_PAGE_SIZE,
  });

  const pageCount = Math.max(
    1,
    Math.ceil(rows.length / paginationModel.pageSize),
  );

  const paginatedRows = useMemo(() => {
    const start = paginationModel.page * paginationModel.pageSize;
    return rows.slice(start, start + paginationModel.pageSize);
  }, [rows, paginationModel.page, paginationModel.pageSize]);

  if (loading || loadingWorkingGroups) {
    return (
      <Box sx={{ minHeight: 320, display: "grid", placeItems: "center" }}>
        <CircularProgress size={28} />
      </Box>
    );
  }

  if (error) {
    return (
      <Box sx={{ minHeight: 220, display: "grid", placeItems: "center" }}>
        <Typography sx={{ color: "#d92d20", fontSize: 14 }}>{error}</Typography>
      </Box>
    );
  }

  return (
    <Box>
      <Box sx={{ display: "flex", flexDirection: "column", gap: 2.5 }}>
        {paginatedRows.map((row) => (
          <GridCard
            key={row.id}
            row={row}
            language={language}
            onView={onView}
          />
        ))}
      </Box>

      <Paper
        elevation={0}
        sx={{
          mt: 2,
          borderRadius: "12px",
          border: `1px solid ${isDark ? alpha("#ffffff", 0.1) : "#f5f5f5"}`,
          overflow: "hidden",
          bgcolor: isDark ? "#101828" : "#ffffff",
        }}
      >
        <CdcGpsfMeetingRequestsTableFooter
          language={language}
          page={paginationModel.page}
          pageCount={pageCount}
          onPrevious={() =>
            setPaginationModel((current) => ({
              ...current,
              page: Math.max(0, current.page - 1),
            }))
          }
          onNext={() =>
            setPaginationModel((current) => ({
              ...current,
              page: Math.min(pageCount - 1, current.page + 1),
            }))
          }
          onSelectPage={(pageIndex) =>
            setPaginationModel((current) => ({
              ...current,
              page: pageIndex,
            }))
          }
        />
      </Paper>
    </Box>
  );
}
