"use client";

import { useState } from "react";

import Box from "@mui/material/Box";
import Typography from "@mui/material/Typography";
import { alpha, useTheme } from "@mui/material/styles";

import { Dropdown, type DropdownOption } from "@/components/ui/dropdown";
import { ChevronDown } from "@/components/ui/icon";
import { IssueStatusSelect } from "@/features/ministry/meeting-summary/components/create-meeting-summary/issue-status-select";
import { StatusBadge } from "@/features/pswg/working-group-issues/components/table/wg-issues-table-cells";
import type { IssueStatus } from "@/features/pswg/working-group-issues/wg-issues-data";
import type { WgIssuesLanguage } from "@/features/pswg/working-group-issues/wg-issues-i18n";

import type { IssueMatrixRow } from "./issue-matrix-data";
import {
  translateIssueMatrixValue,
  type IssueMatrixLanguage,
} from "./issue-matrix-i18n";

const EDITABLE_STATUS_CODES = new Set([
  "IN_PROGRESS",
  "NOT_ADDRESSED",
  "SOLVED",
]);

export type IssueMatrixAgencyOption = {
  id: number;
  name: string;
  logo?: string | null;
};

export type IssueMatrixStatusOption = {
  id: number;
  code: string;
  name: string;
};

export type IssueMatrixEditControl = {
  canEdit: boolean;
  isUpdating: boolean;
  agencyOptions: DropdownOption[];
  statusOptions: IssueMatrixStatusOption[];
  onAgencySave: (row: IssueMatrixRow, agency: IssueMatrixAgencyOption) => void;
  onStatusSave: (
    row: IssueMatrixRow,
    statusId: number,
    statusName: string,
  ) => void;
};

function canEditStatus(row: IssueMatrixRow, canEdit: boolean) {
  return (
    canEdit &&
    row.id > 0 &&
    EDITABLE_STATUS_CODES.has(row.statusCode.trim().toUpperCase())
  );
}

/**
 * The ministry of an issue is its primary agency, so it can be re-assigned on
 * any row, whoever raised the issue. The status rule still applies: only rows
 * the API accepts from the matrix can be edited.
 */
export function canEditAgency(row: IssueMatrixRow, canEdit: boolean) {
  return canEditStatus(row, canEdit);
}

function AgencyCell({
  value,
  image,
}: {
  value: string;
  image?: string | null;
}) {
  const theme = useTheme();

  if (!value || value === "-") {
    return (
      <Typography sx={{ color: theme.palette.text.primary, fontSize: 13 }}>
        -
      </Typography>
    );
  }

  return (
    <Box sx={{ display: "flex", alignItems: "center", gap: 1, minWidth: 0 }}>
      <Box
        component="img"
        src={image || "/images/agencies/default.png"}
        alt={value}
        sx={{
          width: 24,
          height: 24,
          borderRadius: "50%",
          objectFit: "cover",
          flexShrink: 0,
          border: `1px solid ${alpha(theme.palette.divider, 0.8)}`,
        }}
      />
      <Typography
        sx={{
          color: theme.palette.text.primary,
          fontSize: 13,
          fontWeight: 600,
          whiteSpace: "nowrap",
          overflow: "hidden",
          textOverflow: "ellipsis",
        }}
        title={value}
      >
        {value}
      </Typography>
    </Box>
  );
}

const triggerSx = {
  height: "100%",
  bgcolor: "transparent",
  "& .MuiOutlinedInput-notchedOutline": { border: "none" },
  "&:hover .MuiOutlinedInput-notchedOutline": { border: "none" },
  "&.Mui-focused .MuiOutlinedInput-notchedOutline": { border: "none" },
  "& .MuiSelect-select": {
    px: 0,
    py: 0,
    minHeight: "auto !important",
    pr: "28px !important",
  },
} as const;

export function PrimaryAgencySelectCell({
  row,
  control,
}: {
  row: IssueMatrixRow;
  control?: IssueMatrixEditControl;
}) {
  const canEdit = canEditAgency(row, Boolean(control?.canEdit));
  const committedValue = row.primaryAgencyId ? String(row.primaryAgencyId) : "";
  const [draftValue, setDraftValue] = useState<string | null>(null);

  if (!canEdit || !control) {
    return (
      <AgencyCell value={row.primaryAgency} image={row.primaryAgencyImage} />
    );
  }

  const selectedValue = draftValue ?? committedValue;
  const selectedAgency = control.agencyOptions.find(
    (option) => option.value === selectedValue,
  );

  const handleChange = (value: string | string[]) => {
    const nextValue = Array.isArray(value) ? value[0] : value;
    const agency = control.agencyOptions.find(
      (option) => option.value === nextValue,
    );

    if (!agency || nextValue === committedValue) return;

    setDraftValue(nextValue);
    control.onAgencySave(row, {
      id: Number(agency.value),
      name: agency.label,
      logo: agency.logo,
    });
  };

  return (
    <Dropdown
      label={row.primaryAgency}
      options={control.agencyOptions}
      value={selectedValue}
      showCheckbox
      width="100%"
      disabled={control.isUpdating}
      onChange={handleChange}
      onClose={() => setDraftValue(null)}
      triggerSx={triggerSx}
      IconComponent={ChevronDown}
      renderTrigger={() => (
        <AgencyCell
          value={selectedAgency?.label ?? row.primaryAgency}
          image={selectedAgency?.logo ?? row.primaryAgencyImage}
        />
      )}
    />
  );
}

export function IssueMatrixStatusSelectCell({
  row,
  language,
  control,
}: {
  row: IssueMatrixRow;
  language: IssueMatrixLanguage;
  control?: IssueMatrixEditControl;
}) {
  const editable = canEditStatus(row, Boolean(control?.canEdit));

  if (!editable || !control) {
    const wgLanguage: WgIssuesLanguage = language === "kh" ? "km" : "en";

    return (
      <StatusBadge status={row.status as IssueStatus} language={wgLanguage} />
    );
  }

  const handleChange = (statusName: string) => {
    const selected = control.statusOptions.find(
      (status) => status.name.toLowerCase() === statusName.toLowerCase(),
    );

    if (!selected || selected.id === row.statusId) return;

    control.onStatusSave(row, selected.id, selected.name);
  };

  return (
    <IssueStatusSelect
      value={row.status}
      statusOptions={control.statusOptions}
      disabled={control.isUpdating}
      onChange={handleChange}
      getLabel={(statusName) => translateIssueMatrixValue(statusName, language)}
      variant="badge"
      sx={{ width: "100%", minWidth: 0 }}
    />
  );
}
