"use client";

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

import VisibilityOutlinedIcon from "@mui/icons-material/VisibilityOutlined";
import Box from "@mui/material/Box";
import Button from "@mui/material/Button";
import Dialog from "@mui/material/Dialog";
import DialogContent from "@mui/material/DialogContent";
import Typography from "@mui/material/Typography";
import type { GridColDef } from "@mui/x-data-grid";

import { AppDivider } from "@/components/ui/divider";
import { DataTable, DataTableNumberCell } from "@/components/ui/data-table";
import { DocumentLink } from "@/components/ui/document-link";
import { DocumentFileAttachment } from "@/components/ui/document-file-name";
import { IssueStatusBadge } from "@/components/ui/issue-status-badge";
import { useAppLanguage } from "@/components/providers/app-language-provider";
import { formatDate } from "@/lib/date-utils";
import { isDocumentPlaceholder } from "@/lib/document-file";
import {
  AccountCircleIcon,
  CategoryOfIssuesIcon,
  GovernmentAgencyIcon,
  HyperlinkIcon,
  SubmitDateIcon,
  WarningIcon,
} from "@/components/ui/icon";

import type { MeetingRequest } from "../../meeting-request-data";

export type MeetingRequestIssueDetail = {
  id: number;
  issue: string;
  category: string;
  description: string;
  recommendation: string;
  primaryAgency: string;
  primaryAgencyLogo?: string | null;
  secondAgency: string;
  secondAgencyLogo?: string | null;
  thirdAgency: string;
  thirdAgencyLogo?: string | null;
  fourthAgency: string;
  fourthAgencyLogo?: string | null;
  fifthAgency: string;
  fifthAgencyLogo?: string | null;
  status: string;
};

type MeetingRequestForIssueTable = Pick<
  MeetingRequest,
  | "requestedBy"
  | "requestedDate"
  | "documentName"
  | "meetingRequestLetter"
  | "governmentAgencies"
  | "issues"
> & {
  privateSectorWG?: string;
  submittedBy?: string;
};

type MeetingRequestIssueDialogMeetingRequest = Pick<
  MeetingRequest,
  "requestedBy" | "requestedDate" | "documentName" | "meetingRequestLetter"
> & {
  privateSectorWG?: string;
  submittedBy?: string;
};

type MeetingRequestDetailTableProps = {
  meetingRequest: MeetingRequestForIssueTable;
};

const ISSUE_TABLE_ROW_HEIGHT = 60;
const ISSUE_TABLE_HEADER_HEIGHT = 50;
const EMPTY_AGENCY_LABEL = "no data";

export function MeetingRequestDetailTable({
  meetingRequest,
}: MeetingRequestDetailTableProps) {
  const [selectedIssue, setSelectedIssue] =
    useState<MeetingRequestIssueDetail | null>(null);

  const rawIssues = useMemo(
    () =>
      (meetingRequest.issues ?? []) as Array<
        Partial<MeetingRequestIssueDetail>
      >,
    [meetingRequest.issues],
  );

  const agencyLogoByName = useMemo(() => {
    const logos = new Map<string, string | null>();

    for (const agency of meetingRequest.governmentAgencies ?? []) {
      if (agency.name) {
        logos.set(agency.name, agency.logo ?? null);
      }
    }

    for (const issue of rawIssues) {
      const agencySlots = [
        { name: issue.primaryAgency, logo: issue.primaryAgencyLogo },
        { name: issue.secondAgency, logo: issue.secondAgencyLogo },
        { name: issue.thirdAgency, logo: issue.thirdAgencyLogo },
        { name: issue.fourthAgency, logo: issue.fourthAgencyLogo },
        { name: issue.fifthAgency, logo: issue.fifthAgencyLogo },
      ];

      for (const agencySlot of agencySlots) {
        if (agencySlot.name && agencySlot.logo) {
          logos.set(agencySlot.name, agencySlot.logo);
        }
      }
    }

    return logos;
  }, [meetingRequest.governmentAgencies, rawIssues]);

  const issues = useMemo(
    () =>
      rawIssues.map<MeetingRequestIssueDetail>((item, index) => ({
        id: item.id ?? index + 1,
        issue: item.issue ?? "-",
        category: item.category ?? "-",
        description: item.description ?? "-",
        recommendation: item.recommendation ?? "-",
        primaryAgency: item.primaryAgency ?? "-",
        primaryAgencyLogo: item.primaryAgencyLogo ?? null,
        secondAgency: item.secondAgency ?? "-",
        secondAgencyLogo: item.secondAgencyLogo ?? null,
        thirdAgency: item.thirdAgency ?? "-",
        thirdAgencyLogo: item.thirdAgencyLogo ?? null,
        fourthAgency: item.fourthAgency ?? "-",
        fourthAgencyLogo: item.fourthAgencyLogo ?? null,
        fifthAgency: item.fifthAgency ?? "-",
        fifthAgencyLogo: item.fifthAgencyLogo ?? null,
        status: item.status ?? "-",
      })),
    [rawIssues],
  );

  const issueColumns = useMemo<GridColDef<MeetingRequestIssueDetail>[]>(
    () => [
      {
        field: "id",
        headerName: "No.",
        width: 64,
        minWidth: 64,
        align: "center",
        headerAlign: "center",
        sortable: false,
        filterable: false,
        disableColumnMenu: true,
        renderCell: (params) => (
          <DataTableNumberCell
            value={
              params.api.getRowIndexRelativeToVisibleRows(params.row.id) + 1
            }
          />
        ),
      },
      {
        field: "issue",
        headerName: "Issue",
        width: 260,
        minWidth: 220,
        renderCell: (params) => <IssueTextCell value={params.row.issue} bold />,
      },
      {
        field: "category",
        headerName: "Category of Issue",
        width: 210,
        minWidth: 190,
        renderCell: (params) => <IssueTextCell value={params.row.category} />,
      },
      {
        field: "description",
        headerName: "Issue Description",
        width: 320,
        minWidth: 260,
        renderCell: (params) => (
          <IssueLongTextCell value={params.row.description} />
        ),
      },
      {
        field: "recommendation",
        headerName: "Recommendation",
        width: 320,
        minWidth: 260,
        renderCell: (params) => (
          <IssueLongTextCell value={params.row.recommendation} />
        ),
      },
      {
        field: "primaryAgency",
        headerName: "Gov't primary Agency",
        width: 210,
        minWidth: 190,
        renderCell: (params) => (
          <AgencyCell
            value={params.row.primaryAgency}
            logo={params.row.primaryAgencyLogo}
            logoByName={agencyLogoByName}
            emptyLabel="-"
          />
        ),
      },
      {
        field: "secondAgency",
        headerName: "Gov't second Agency",
        width: 210,
        minWidth: 190,
        renderCell: (params) => (
          <AgencyCell
            value={params.row.secondAgency}
            logo={params.row.secondAgencyLogo}
            logoByName={agencyLogoByName}
            emptyLabel="-"
          />
        ),
      },
      {
        field: "thirdAgency",
        headerName: "Gov't third Agency",
        width: 210,
        minWidth: 190,
        renderCell: (params) => (
          <AgencyCell
            value={params.row.thirdAgency}
            logo={params.row.thirdAgencyLogo}
            logoByName={agencyLogoByName}
            emptyLabel="-"
          />
        ),
      },
      {
        field: "fourthAgency",
        headerName: "Gov't fourth Agency",
        width: 210,
        minWidth: 190,
        renderCell: (params) => (
          <AgencyCell
            value={params.row.fourthAgency}
            logo={params.row.fourthAgencyLogo}
            logoByName={agencyLogoByName}
            emptyLabel="-"
          />
        ),
      },
      {
        field: "fifthAgency",
        headerName: "Gov't fifth Agency",
        width: 210,
        minWidth: 190,
        renderCell: (params) => (
          <AgencyCell
            value={params.row.fifthAgency}
            logo={params.row.fifthAgencyLogo}
            logoByName={agencyLogoByName}
            emptyLabel="-"
          />
        ),
      },
      {
        field: "status",
        headerName: "Status",
        width: 170,
        minWidth: 150,
        align: "center",
        renderCell: (params) => <IssueStatusCell value={params.row.status} />,
      },
      {
        field: "action",
        headerName: "Action",
        width: 140,
        minWidth: 140,
        align: "center",
        headerAlign: "center",
        sortable: false,
        filterable: false,
        disableColumnMenu: true,
        renderCell: (params) => (
          <IssueViewButton
            issue={params.row}
            onViewIssue={() => setSelectedIssue(params.row)}
          />
        ),
      },
    ],
    [agencyLogoByName],
  );

  const tableHeight =
    ISSUE_TABLE_HEADER_HEIGHT +
    Math.max(issues.length, 1) * ISSUE_TABLE_ROW_HEIGHT;

  return (
    <>
      <DataTable
        rows={issues}
        columns={issueColumns}
        getRowId={(issue) => issue.id}
        emptyMessage="No issues found."
        height={tableHeight}
        hidePagination
        rowHeight={ISSUE_TABLE_ROW_HEIGHT}
        columnHeaderHeight={ISSUE_TABLE_HEADER_HEIGHT}
        enableColumnMenu
        paperSx={{
          borderRadius: "6px",
          border: "1px solid var(--mr-border)",
          bgcolor: "var(--mr-card)",
          backgroundImage: "none",
        }}
        dataGridSx={{
          bgcolor: "var(--mr-card)",
          backgroundImage: "none",

          "& .MuiDataGrid-columnHeaders": {
            bgcolor: "var(--mr-header)",
            borderBottom: "1px solid var(--mr-border)",
          },

          "& .MuiDataGrid-columnHeader": {
            px: 2,
            bgcolor: "var(--mr-header)",
          },

          "& .MuiDataGrid-columnHeaderTitle": {
            color: "var(--mr-muted)",
            fontSize: 12,
            fontWeight: 500,
            whiteSpace: "nowrap",
            overflow: "visible",
            textOverflow: "clip",
          },

          "& .MuiDataGrid-columnHeaderTitleContainer": {
            overflow: "visible",
          },

          "& .MuiDataGrid-cell": {
            px: 2,
            color: "var(--mr-text)",
            bgcolor: "var(--mr-card)",
            borderColor: "var(--mr-border)",
          },

          "& .MuiDataGrid-row": {
            bgcolor: "var(--mr-card)",
          },

          "& .MuiDataGrid-row:hover": {
            bgcolor: "var(--mr-card)",
          },

          "& .MuiDataGrid-withBorderColor": {
            borderColor: "var(--mr-border)",
          },

          "& .MuiDataGrid-main": {
            overflow: "hidden",
          },

          "& .MuiDataGrid-virtualScroller": {
            overflowX: "auto !important",
            overflowY: "auto !important",
            bgcolor: "var(--mr-card)",
          },
        }}
      />

      <MeetingRequestIssueDetailDialog
        open={Boolean(selectedIssue)}
        issue={selectedIssue}
        meetingRequest={meetingRequest}
        agencyLogoByName={agencyLogoByName}
        onClose={() => setSelectedIssue(null)}
      />
    </>
  );
}

function IssueViewButton({
  issue,
  onViewIssue,
}: {
  issue: MeetingRequestIssueDetail;
  onViewIssue: (issue: MeetingRequestIssueDetail) => void;
}) {
  return (
    <Button
      startIcon={<VisibilityOutlinedIcon sx={{ fontSize: 18 }} />}
      onClick={() => onViewIssue(issue)}
      sx={{
        minWidth: 0,
        color: "var(--mr-muted)",
        textTransform: "none",
        fontSize: 12,
        fontWeight: 400,
        whiteSpace: "nowrap",
        "& .MuiButton-startIcon": {
          mr: 0.5,
        },
      }}
    >
      View Detail
    </Button>
  );
}

export function MeetingRequestIssueDetailDialog({
  open,
  issue,
  meetingRequest,
  agencyLogoByName,
  onClose,
  dialogZIndex = 1300,
}: {
  open: boolean;
  issue: MeetingRequestIssueDetail | null;
  meetingRequest: MeetingRequestIssueDialogMeetingRequest;
  agencyLogoByName: Map<string, string | null>;
  onClose: () => void;
  dialogZIndex?: number;
}) {
  const { language } = useAppLanguage();
  const documentPath =
    meetingRequest.meetingRequestLetter?.trim() ||
    meetingRequest.documentName;

  if (!issue) {
    return null;
  }

  return (
    <Dialog
      open={open}
      onClose={onClose}
      maxWidth={false}
      sx={{ zIndex: dialogZIndex }}
      slotProps={{
        backdrop: {
          sx: {
            backgroundColor: "rgba(0, 0, 0, 0.45)",
            backdropFilter: "none",
          },
        },
        paper: {
          sx: {
            width: { xs: "calc(100vw - 32px)", md: 795 },
            maxWidth: "calc(100vw - 32px)",
            height: { xs: "auto", md: 708 },
            maxHeight: { xs: "calc(100vh - 32px)", md: 708 },
            borderRadius: "12px",
            bgcolor: "#FFFFFF",
            backgroundImage: "none",
            color: "#181D27",
            overflow: "hidden",
            opacity: 1,
            filter: "none",
          },
        },
      }}
    >
      <Box
        sx={{
          height: 70,
          px: 3,
          display: "flex",
          alignItems: "center",
        }}
      >
        <Typography
          sx={{
            fontSize: 20,
            fontWeight: 500,
            color: "var(--mr-text)",
            letterSpacing: "-0.4px",
          }}
        >
          Issues Detail
        </Typography>
      </Box>
      <AppDivider />

      <DialogContent
        sx={{
          px: 3,
          py: 3,
          bgcolor: "var(--mr-card)",
          overflowY: "auto",
        }}
      >
        <Typography
          sx={{
            pb: 2.75,
            fontSize: { xs: 20, md: 24 },
            fontWeight: 600,
            color: "var(--mr-text)",
            lineHeight: 1.25,
          }}
        >
          {issue.issue}
        </Typography>
        <AppDivider sx={{ mx: -3 }} />

        <Box sx={{ py: 2.75 }}>
          <Typography
            sx={{
              mb: 2,
              fontSize: 16,
              fontWeight: 700,
              color: "var(--mr-text)",
            }}
          >
            Submit Details
          </Typography>

          <Box
            sx={{
              display: "grid",
              gridTemplateColumns: { xs: "1fr", md: "1fr 1fr" },
              columnGap: 7,
              rowGap: 2,
            }}
          >
            <IssueDetailInfo
              icon={<AccountCircleIcon />}
              label="Submitted by"
              value={
                meetingRequest.privateSectorWG ?? meetingRequest.requestedBy
              }
            />

            <IssueDetailInfo
              icon={<SubmitDateIcon />}
              label="Submitted Date"
              value={formatDate(meetingRequest.requestedDate, language)}
            />

            <IssueDetailInfo
              icon={<HyperlinkIcon />}
              label="Issue Document"
              value={
                isDocumentPlaceholder(documentPath) || !documentPath ? (
                  "-"
                ) : (
                  <DocumentLink
                    file={{ path: documentPath }}
                    sx={{
                      display: "inline-flex",
                      alignItems: "center",
                      minWidth: 0,
                    }}
                  >
                    <DocumentFileAttachment
                      value={documentPath}
                      emptyLabel="-"
                      iconSize={20}
                    />
                  </DocumentLink>
                )
              }
            />

            <IssueDetailInfo
              icon={<CategoryOfIssuesIcon />}
              label="Category of Issues"
              value={issue.category}
            />

            <IssueDetailInfo
              icon={<GovernmentAgencyIcon />}
              label="Government Agency"
              value={
                <AgencyCell
                  value={issue.primaryAgency}
                  logo={issue.primaryAgencyLogo}
                  logoByName={agencyLogoByName}
                />
              }
            />

            <IssueDetailInfo
              icon={<WarningIcon />}
              label="Status"
              value={<IssueStatusCell value={issue.status} />}
            />

            <IssueDetailInfo
              icon={<GovernmentAgencyIcon />}
              label="Gov't Second Agency"
              value={
                <AgencyCell
                  value={issue.secondAgency}
                  logo={issue.secondAgencyLogo}
                  logoByName={agencyLogoByName}
                />
              }
            />

            <IssueDetailInfo
              icon={<GovernmentAgencyIcon />}
              label="Gov't Third Agency"
              value={
                <AgencyCell
                  value={issue.thirdAgency}
                  logo={issue.thirdAgencyLogo}
                  logoByName={agencyLogoByName}
                />
              }
            />

            <IssueDetailInfo
              icon={<GovernmentAgencyIcon />}
              label="Gov't Fourth Agency"
              value={
                <AgencyCell
                  value={issue.fourthAgency}
                  logo={issue.fourthAgencyLogo}
                  logoByName={agencyLogoByName}
                />
              }
            />

            <IssueDetailInfo
              icon={<GovernmentAgencyIcon />}
              label="Gov't Fifth Agency"
              value={
                <AgencyCell
                  value={issue.fifthAgency}
                  logo={issue.fifthAgencyLogo}
                  logoByName={agencyLogoByName}
                />
              }
            />
          </Box>
        </Box>

        <AppDivider sx={{ mx: -3 }} />

        <IssueDetailTextSection
          title="Issue Descriptions"
          content={issue.description}
        />

        <AppDivider sx={{ mx: -3 }} />

        <IssueDetailTextSection
          title="Recommendations"
          content={issue.recommendation}
        />
      </DialogContent>
    </Dialog>
  );
}

const ISSUE_DETAIL_LABEL_WIDTH = 152;

function IssueDetailInfo({
  icon,
  label,
  value,
  labelWidth = ISSUE_DETAIL_LABEL_WIDTH,
}: {
  icon: ReactNode;
  label: string;
  value: ReactNode;
  labelWidth?: number;
}) {
  return (
    <Box
      sx={{
        minWidth: 0,
        display: "flex",
        alignItems: "center",
        gap: 0.75,
      }}
    >
      <Box
        component="span"
        sx={{
          flexShrink: 0,
          display: "flex",
          alignItems: "center",
          justifyContent: "center",
          width: 20,
          color: "var(--mr-muted)",
        }}
      >
        {icon}
      </Box>

      <Box
        sx={{
          flex: 1,
          minWidth: 0,
          display: "flex",
          alignItems: "center",
          gap: 0.75,
        }}
      >
        <Typography
          sx={{
            width: labelWidth,
            flexShrink: 0,
            fontSize: 13,
            fontWeight: 400,
            color: "var(--mr-muted)",
            whiteSpace: "nowrap",
            lineHeight: "22px",
          }}
        >
          {label} :
        </Typography>

        {typeof value === "string" ? (
          <Box
            component="span"
            sx={{
              flex: 1,
              minWidth: 0,
              overflow: "hidden",
              textOverflow: "ellipsis",
              whiteSpace: "nowrap",
              display: "block",
              cursor: "default",
            }}
          >
            <Typography
              component="span"
              sx={{
                fontSize: 13,
                fontWeight: 500,
                color: "var(--mr-text)",
                lineHeight: "22px",
              }}
            >
              {value}
            </Typography>
          </Box>
        ) : (
          <Box
            sx={{
              flex: 1,
              minWidth: 0,
              display: "flex",
              alignItems: "center",
            }}
          >
            {value}
          </Box>
        )}
      </Box>
    </Box>
  );
}

function IssueDetailTextSection({
  title,
  content,
}: {
  title: string;
  content: string;
}) {
  return (
    <Box sx={{ py: 2.75 }}>
      <Typography
        sx={{
          mb: 2,
          fontSize: 16,
          fontWeight: 700,
          color: "var(--mr-text)",
        }}
      >
        {title}
      </Typography>

      <Typography
        sx={{
          fontSize: 13,
          fontWeight: 400,
          color: "var(--mr-text)",
          lineHeight: "22px",
          textAlign: "justify",
        }}
      >
        {content}
      </Typography>
    </Box>
  );
}

function IssueTextCell({
  value,
  align = "left",
  bold = false,
}: {
  value: string;
  align?: "left" | "center" | "right";
  bold?: boolean;
}) {
  return (
    <Typography
      className="font-kh"
      sx={{
        width: "100%",
        overflow: "hidden",
        textOverflow: "ellipsis",
        whiteSpace: "nowrap",
        color: "var(--mr-text)",
        fontSize: 12,
        fontWeight: bold ? 500 : 400,
        textAlign: align,
      }}
    >
      {value}
    </Typography>
  );
}

function IssueLongTextCell({ value }: { value: string }) {
  return (
    <Typography
      className="font-kh"
      sx={{
        width: "100%",
        overflow: "hidden",
        textOverflow: "ellipsis",
        whiteSpace: "nowrap",
        color: "var(--mr-text)",
        fontSize: 12,
        fontWeight: 400,
        cursor: "default",
      }}
    >
      {value}
    </Typography>
  );
}

function IssueStatusCell({ value }: { value: string }) {
  return <IssueStatusBadge status={value} />;
}

function AgencyCell({
  value,
  logo,
  logoByName,
  emptyLabel = EMPTY_AGENCY_LABEL,
}: {
  value: string;
  logo?: string | null;
  logoByName?: Map<string, string | null>;
  emptyLabel?: string;
}) {
  if (isEmptyAgencyValue(value)) {
    return (
      <Typography
        sx={{
          fontSize: 12,
          fontWeight: 400,
          color: "var(--mr-text)",
        }}
      >
        {emptyLabel}
      </Typography>
    );
  }

  const resolvedLogo = logo ?? logoByName?.get(value) ?? null;

  return (
    <Box sx={{ display: "flex", alignItems: "center", gap: 1, minWidth: 0 }}>
      {resolvedLogo ? (
        <Box
          component="img"
          src={resolvedLogo}
          alt={value}
          sx={{
            width: 24,
            height: 24,
            borderRadius: "50%",
            objectFit: "cover",
            flexShrink: 0,
          }}
        />
      ) : null}

      <Box
        component="span"
        sx={{
          minWidth: 0,
          overflow: "hidden",
          textOverflow: "ellipsis",
          whiteSpace: "nowrap",
          display: "block",
          cursor: "default",
        }}
      >
        <Typography
          component="span"
          sx={{
            fontSize: 12,
            fontWeight: 400,
            color: "var(--mr-text)",
          }}
        >
          {value}
        </Typography>
      </Box>
    </Box>
  );
}

function isEmptyAgencyValue(value: string) {
  return !value || value === "-" || value === "Not Uploaded";
}
