"use client";

import {
    useEffect,
    useMemo,
    useRef,
    useState,
    type ChangeEvent,
    type MouseEvent,
} from "react";

import Box from "@mui/material/Box";
import Button from "@mui/material/Button";
import ButtonBase from "@mui/material/ButtonBase";
import Checkbox from "@mui/material/Checkbox";
import CircularProgress from "@mui/material/CircularProgress";
import MenuItem from "@mui/material/MenuItem";
import Popover from "@mui/material/Popover";
import Select from "@mui/material/Select";
import TextField from "@mui/material/TextField";
import Typography from "@mui/material/Typography";
import { alpha, useTheme } from "@mui/material/styles";

import CloudUploadOutlinedIcon from "@mui/icons-material/CloudUploadOutlined";

import type { MeetingRequestRow } from "../../meeting-request-data";
import {
    getMeetingRequestFont,
    type UiLang,
} from "../../meeting-request-i18n";
import { AlertDialog } from "@/components/ui/alert-dialog";
import { DocumentLink } from "@/components/ui/document-link";
import { DocumentFileAttachment } from "@/components/ui/document-file-name";
import {
    getFormBorderColor,
    getFormSoftBg,
} from "@/components/ui/form";
import { AppTextEditor } from "@/components/ui/text-editor";
import { CreateIssueDialog } from "@/features/pswg/working-group-issues/components/create-issuses";
import {
    formatFileSize,
    isDocumentPlaceholder,
} from "@/lib/document-file";
import {
    meetingRequestService,
    resolveAssetUrl,
    type ApiGovernmentAgency,
    type ApiIssue,
    type CreateMeetingRequestPayload,
} from "../../service/meeting-request-service";

type CreateIssue = {
    id: number;
    no: number;
    issue: string;
    description: string;
};

export type EditableMeetingRequest = {
    id: string;
    title: string;
    governmentAgency: string;
    description: string;
    issues: CreateIssue[];
    requestLetterFileName?: string;
};

type MeetingRequestCreateProps = {
    language?: UiLang;
    onBack: () => void;
    mode?: "create" | "edit";
    editRow?: MeetingRequestRow | null;
    onSubmit?: (
        payload?: EditableMeetingRequest,
        // "sendFailed" means the meeting request was saved but the send step
        // did not confirm, so the list should tell the user to check it.
        options?: { sent: boolean; sendFailed?: boolean },
    ) => void;
};

function mergeUniqueAgencies(
    agencyResult: ApiGovernmentAgency[],
    agencyToAdd: ApiGovernmentAgency | null,
): ApiGovernmentAgency[] {
    if (!agencyToAdd) return agencyResult;

    const exists = agencyResult.some((agency) => agency.id === agencyToAdd.id);
    if (exists) return agencyResult;

    return [agencyToAdd, ...agencyResult];
}


function apiIssueToCreateIssue(issue: ApiIssue, index: number): CreateIssue {
    return {
        id: issue.id,
        no: index + 1,
        issue: issue.title || "-",
        description: issue.description || "-",
    };
}

function getFileSize(file: File | null | undefined) {
    if (!file) return "";
    return formatFileSize(file.size);
}

const MEETING_REQUEST_PDF_MAX_BYTES = 10 * 1024 * 1024;

function isPdfFile(file: File) {
    return (
        file.type === "application/pdf" || file.name.toLowerCase().endsWith(".pdf")
    );
}

function stripHtml(value: string) {
    if (!value) return "";
    return value
        .replace(/<style[\s\S]*?<\/style>/gi, "")
        .replace(/<script[\s\S]*?<\/script>/gi, "")
        .replace(/<[^>]*>/g, " ")
        .replace(/&nbsp;/g, " ")
        .replace(/\s+/g, " ")
        .trim();
}

function ChevronDownIcon({ size = 18 }: { size?: number }) {
    return (
        <Box
            component="svg"
            width={size}
            height={size}
            viewBox="0 0 20 20"
            fill="none"
            sx={{ display: "block", flexShrink: 0 }}
        >
            <path
                d="M5 7.5L10 12.5L15 7.5"
                stroke="currentColor"
                strokeWidth="1.8"
                strokeLinecap="round"
                strokeLinejoin="round"
            />
        </Box>
    );
}

function CompletedIcon() {
    return (
        <Box
            component="span"
            sx={{
                width: 14,
                height: 14,
                borderRadius: "50%",
                backgroundColor: "#12b76a",
                color: "#ffffff",
                display: "inline-flex",
                alignItems: "center",
                justifyContent: "center",
                fontSize: 9,
                fontWeight: 800,
                lineHeight: 1,
                flexShrink: 0,
            }}
        >
            ✓
        </Box>
    );
}

function FormLabel({
    children,
    required,
}: {
    children: string;
    required?: boolean;
}) {
    const theme = useTheme();
    const isDark = theme.palette.mode === "dark";

    return (
        <Typography
            sx={{
                mb: 1.75,
                color: isDark ? alpha("#ffffff", 0.86) : "#414651",
                fontSize: 13,
                fontWeight: 500,
                lineHeight: "normal",
            }}
        >
            {children}{" "}
            {required ? (
                <Box component="span" sx={{ color: "#f04438" }}>
                    *
                </Box>
            ) : null}
        </Typography>
    );
}

function AgencyLogo({
    logo,
    name,
}: {
    logo?: string | null;
    name: string;
}) {
    const logoSrc = resolveAssetUrl(logo);

    if (!logoSrc) return null;

    return (
        <Box
            component="img"
            src={logoSrc}
            alt={name}
            onError={(event) => {
                event.currentTarget.style.display = "none";
            }}
            sx={{
                width: 24,
                height: 24,
                borderRadius: "50%",
                objectFit: "cover",
                flexShrink: 0,
                opacity: 1,
                border: "1px solid #e9eaeb",
                backgroundColor: "#ffffff",
            }}
        />
    );
}

function AgencySelectField({
    label,
    required,
    value,
    agencies,
    loading,
    disabled = false,
    onChange,
}: {
    label: string;
    required?: boolean;
    value: number | "";
    agencies: ApiGovernmentAgency[];
    loading: boolean;
    disabled?: boolean;
    onChange: (value: number | "") => void;
}) {
    return (
        <Box>
            <FormLabel required={required}>{label}</FormLabel>

            <Select
                fullWidth
                displayEmpty
                value={value}
                disabled={disabled}
                onChange={(event) => {
                    if (disabled) return;

                    const nextValue = String(event.target.value);
                    onChange(nextValue === "" ? "" : Number(nextValue));
                }}
                renderValue={(selected) => {
                    const selectedValue = String(selected || "");

                    if (!selectedValue) {
                        return (
                            <Typography sx={{ color: "#a4a7ae", fontSize: 14 }}>
                                Select agency
                            </Typography>
                        );
                    }

                    const agency = agencies.find(
                        (item) => item.id === Number(selectedValue),
                    );

                    if (!agency) {
                        return (
                            <Typography sx={{ color: "#a4a7ae", fontSize: 14 }}>
                                Select agency
                            </Typography>
                        );
                    }

                    return (
                        <Box sx={{ display: "flex", alignItems: "center", gap: 1 }}>
                            <AgencyLogo logo={agency.logo} name={agency.name} />

                            <Typography sx={{ fontSize: 12, fontWeight: 500, color: "#000000" }}>
                                {agency.name}
                            </Typography>
                        </Box>
                    );
                }}
                sx={{
                    height: 50,
                    borderRadius: "6px",
                    backgroundColor: disabled ? "#f9fafb" : "#ffffff",
                    "&.Mui-disabled": {
                        color: "#101828",
                        cursor: "not-allowed",
                    },
                    "& .MuiSelect-select": {
                        display: "flex",
                        alignItems: "center",
                        px: "18px",
                    },
                    "& .MuiSelect-select.Mui-disabled": {
                        opacity: 1,
                        WebkitTextFillColor: "#101828",
                    },
                    "& .MuiSelect-icon.Mui-disabled": {
                        display: "none",
                    },
                    "& img": {
                        opacity: 1,
                    },
                }}
            >
                <MenuItem value="">
                    <Typography sx={{ color: "#a4a7ae", fontSize: 14 }}>
                        Select agency
                    </Typography>
                </MenuItem>

                {loading ? (
                    <MenuItem disabled value="loading">
                        <CircularProgress size={16} sx={{ mr: 1 }} />
                        Loading...
                    </MenuItem>
                ) : null}

                {!loading && agencies.length === 0 ? (
                    <MenuItem disabled value="empty">
                        No agency found
                    </MenuItem>
                ) : null}

                {!loading &&
                    agencies.map((agency) => (
                        <MenuItem key={agency.id} value={agency.id}>
                            <Box sx={{ display: "flex", alignItems: "center", gap: 1 }}>
                                <AgencyLogo logo={agency.logo} name={agency.name} />

                                <Typography sx={{ fontSize: 14 }}>{agency.name}</Typography>
                            </Box>
                        </MenuItem>
                    ))}
            </Select>
        </Box>
    );
}

function SelectLikeField({
    placeholder,
    selectedText,
    onClick,
}: {
    placeholder: string;
    selectedText?: string;
    onClick?: (event: MouseEvent<HTMLDivElement>) => void;
}) {
    const theme = useTheme();
    const isDark = theme.palette.mode === "dark";
    const clickable = Boolean(onClick);

    return (
        <Box
            onClick={onClick}
            sx={{
                height: 50,
                px: "18px",
                borderRadius: "6px",
                border: `1px solid ${isDark ? alpha("#ffffff", 0.12) : "#e9eaeb"}`,
                backgroundColor: isDark ? alpha("#ffffff", 0.04) : "#ffffff",
                display: "flex",
                alignItems: "center",
                justifyContent: "space-between",
                gap: 1.5,
                cursor: clickable ? "pointer" : "default",
            }}
        >
            <Typography
                noWrap
                sx={{
                    color: selectedText
                        ? isDark
                            ? "#ffffff"
                            : "#181d27"
                        : "#a4a7ae",
                    fontSize: 13,
                    fontWeight: 500,
                    minWidth: 0,
                }}
            >
                {selectedText || placeholder}
            </Typography>

            <Box
                sx={{
                    width: 28,
                    height: 28,
                    display: "grid",
                    placeItems: "center",
                    color: isDark ? alpha("#ffffff", 0.65) : "#667085",
                }}
            >
                <ChevronDownIcon size={18} />
            </Box>
        </Box>
    );
}

function UploadBox({
    compact = false,
    file,
    fileLabel = "Request Doc",
    initialFileName,
    onFileChange,
}: {
    compact?: boolean;
    file?: File | null;
    fileLabel?: string;
    initialFileName?: string;
    onFileChange?: (file: File | null) => void;
}) {
    const theme = useTheme();
    const isDark = theme.palette.mode === "dark";
    const [fileError, setFileError] = useState<string | null>(null);

    function handleFileChange(event: ChangeEvent<HTMLInputElement>) {
        const selectedFile = event.target.files?.[0] ?? null;

        if (!selectedFile) {
            onFileChange?.(null);
            event.target.value = "";
            return;
        }

        if (!isPdfFile(selectedFile)) {
            setFileError("Only PDF file is allowed");
            onFileChange?.(null);
            event.target.value = "";
            return;
        }

        if (selectedFile.size > MEETING_REQUEST_PDF_MAX_BYTES) {
            setFileError("PDF file size must not exceed 10 MB.");
            onFileChange?.(null);
            event.target.value = "";
            return;
        }

        setFileError(null);
        onFileChange?.(selectedFile);
        event.target.value = "";
    }

    const hasFile = Boolean(file || initialFileName);
    const documentValue = file?.name || initialFileName || fileLabel;
    const documentPath =
        !file && initialFileName && !isDocumentPlaceholder(initialFileName)
            ? initialFileName
            : null;
    const documentSizeLabel = file ? getFileSize(file) : null;

    if (compact || hasFile) {
        return (
            <Box>
                <Box
                    sx={{
                        display: "flex",
                        flexDirection: { xs: "column", sm: "row" },
                        alignItems: { xs: "stretch", sm: "center" },
                        gap: { xs: 1.5, sm: 3 },
                    }}
                >
                    <Box
                        sx={{
                            width: { xs: "100%", sm: 360 },
                            maxWidth: "100%",
                            height: 78,
                            px: 2,
                            borderRadius: "8px",
                            backgroundColor: isDark ? alpha("#ffffff", 0.04) : "#fafafa",
                            display: "flex",
                            alignItems: "center",
                            gap: 2,
                            overflow: "hidden",
                            boxSizing: "border-box",
                        }}
                    >
                        <Box sx={{ minWidth: 0, flex: 1 }}>
                            <DocumentLink
                                file={documentPath ? { path: documentPath } : null}
                                sx={{
                                    display: "block",
                                    minWidth: 0,
                                    maxWidth: "100%",
                                }}
                            >
                                <DocumentFileAttachment
                                    value={documentValue}
                                    fileSize={documentSizeLabel}
                                    iconSize={40}
                                    emptyLabel={fileLabel}
                                />
                            </DocumentLink>
                        </Box>

                        <Box sx={{ width: 112, flexShrink: 0 }}>
                            <Box sx={{ display: "flex", alignItems: "center", gap: 0.75 }}>
                                <CompletedIcon />

                                <Typography sx={{ color: "#535862", fontSize: 13 }}>
                                    Completed
                                </Typography>
                            </Box>

                            <Box
                                sx={{
                                    mt: 1.25,
                                    height: 3,
                                    borderRadius: 999,
                                    backgroundColor: "#12b76a",
                                }}
                            />
                        </Box>
                    </Box>

                    <Box
                        component="label"
                        sx={{
                            width: { xs: "100%", sm: 96 },
                            height: 78,
                            borderRadius: "12px",
                            border: `1px dashed ${isDark ? alpha("#ffffff", 0.18) : "#d5d7da"
                                }`,
                            backgroundColor: isDark ? alpha("#ffffff", 0.03) : "#ffffff",
                            display: "grid",
                            placeItems: "center",
                            cursor: "pointer",
                            boxSizing: "border-box",
                        }}
                    >
                        <input
                            hidden
                            type="file"
                            accept=".pdf,application/pdf"
                            onChange={handleFileChange}
                        />
                        <CloudUploadOutlinedIcon
                            sx={{
                                fontSize: 34,
                                color: theme.palette.primary.main,
                            }}
                        />
                    </Box>
                </Box>

                {fileError ? (
                    <Typography sx={{ mt: 1, color: "#d92d20", fontSize: 13 }}>
                        {fileError}
                    </Typography>
                ) : null}
            </Box>
        );
    }

    return (
        <Box>
            <Box
                component="label"
                sx={{
                    height: 135,
                    border: `1px dashed ${getFormBorderColor(theme)}`,
                    borderRadius: "10px",
                    bgcolor: getFormSoftBg(theme),
                    display: "flex",
                    alignItems: "center",
                    justifyContent: "center",
                    flexDirection: "column",
                    cursor: "pointer",
                    transition: "0.2s",
                    "&:hover": {
                        bgcolor: alpha(theme.palette.primary.main, 0.1),
                        borderColor: theme.palette.primary.main,
                    },
                }}
            >
                <input
                    hidden
                    type="file"
                    accept=".pdf,application/pdf"
                    onChange={handleFileChange}
                />

                <CloudUploadOutlinedIcon
                    sx={{
                        fontSize: 34,
                        color: theme.palette.primary.main,
                        mb: 0.5,
                    }}
                />

                <Typography
                    sx={{
                        fontSize: 11,
                        color: theme.palette.text.secondary,
                        fontWeight: 600,
                    }}
                >
                    <Box
                        component="span"
                        sx={{
                            color: theme.palette.primary.main,
                            fontWeight: 700,
                        }}
                    >
                        Click to upload
                    </Box>{" "}
                    or drag and drop
                </Typography>

                <Typography sx={{ fontSize: 10, color: theme.palette.text.secondary }}>
                    pdf 10MB
                </Typography>
            </Box>

            {fileError ? (
                <Typography sx={{ mt: 1, color: "#d92d20", fontSize: 13 }}>
                    {fileError}
                </Typography>
            ) : null}
        </Box>
    );
}

function IssueSelectorPopover({
    anchorEl,
    issues,
    selectedIds,
    loading,
    onClose,
    onConfirm,
}: {
    anchorEl: HTMLElement | null;
    issues: ApiIssue[];
    selectedIds: number[];
    loading: boolean;
    onClose: () => void;
    onConfirm: (ids: number[]) => void;
}) {
    const theme = useTheme();
    const isDark = theme.palette.mode === "dark";
    const [draftIds, setDraftIds] = useState<number[]>(() => selectedIds);

    const anchorPosition = useMemo(() => {
        if (!anchorEl) return undefined;

        const rect = anchorEl.getBoundingClientRect();

        return {
            top: rect.bottom + 8,
            left: rect.left + rect.width / 2 + 120,
        };
    }, [anchorEl]);

    function toggleIssue(id: number) {
        setDraftIds((current: number[]) =>
            current.includes(id)
                ? current.filter((item) => item !== id)
                : [...current, id],
        );
    }

    function handleSelectAll() {
        setDraftIds(issues.map((item) => item.id));
    }

    return (
        <Popover
            open={Boolean(anchorEl)}
            onClose={onClose}
            anchorReference="anchorPosition"
            anchorPosition={anchorPosition}
            transformOrigin={{
                vertical: "top",
                horizontal: "center",
            }}
            marginThreshold={16}
            disableScrollLock
            slotProps={{
                paper: {
                    sx: {
                        width: 480,
                        maxWidth: "calc(100vw - 48px)",
                        borderRadius: "12px",
                        backgroundColor: isDark ? "#101828" : "#ffffff",
                        border: `1px solid ${isDark ? alpha("#ffffff", 0.12) : "#e9eaeb"
                            }`,
                        boxShadow: "0px 18px 45px rgba(16, 24, 40, 0.18)",
                        p: 2,
                        overflow: "hidden",
                    },
                },
            }}
        >
            <Box
                sx={{
                    borderRadius: "8px",
                    border: `1px solid ${isDark ? alpha("#ffffff", 0.1) : "#f2f4f7"
                        }`,
                    overflow: "hidden",
                    backgroundColor: isDark ? "#101828" : "#ffffff",
                }}
            >
                <Box
                    sx={{
                        display: "grid",
                        gridTemplateColumns: "56px 1fr 1.5fr 76px",
                        backgroundColor: isDark ? "#111827" : "#fafafa",
                    }}
                >
                    {["NO", "Issue", "Issues Description", "Select"].map((item) => (
                        <Typography
                            key={item}
                            sx={{
                                px: 1.25,
                                py: 1.25,
                                color: "#717680",
                                fontSize: 13,
                                fontWeight: 500,
                            }}
                        >
                            {item}
                        </Typography>
                    ))}
                </Box>

                {loading ? (
                    <Box
                        sx={{
                            minHeight: 80,
                            display: "flex",
                            alignItems: "center",
                            justifyContent: "center",
                            gap: 1,
                        }}
                    >
                        <CircularProgress size={18} />

                        <Typography sx={{ fontSize: 13, color: "#535862" }}>
                            Loading issues...
                        </Typography>
                    </Box>
                ) : null}

                {!loading && issues.length === 0 ? (
                    <Typography sx={{ p: 2, fontSize: 13, color: "#d92d20" }}>
                        No issue found
                    </Typography>
                ) : null}

                {!loading &&
                    issues.map((item, index) => (
                        <Box
                            key={item.id}
                            sx={{
                                display: "grid",
                                gridTemplateColumns: "56px 1fr 1.5fr 76px",
                                minHeight: 54,
                                borderTop: `1px solid ${isDark ? alpha("#ffffff", 0.08) : "#f2f4f7"
                                    }`,
                                alignItems: "center",
                            }}
                        >
                            <Typography sx={{ px: 1.25, fontSize: 13, color: "#344054" }}>
                                {index + 1}
                            </Typography>

                            <Typography
                                noWrap
                                sx={{
                                    px: 1.25,
                                    fontSize: 14,
                                    fontWeight: 700,
                                    color: isDark ? "#ffffff" : "#181d27",
                                }}
                            >
                                {item.title}
                            </Typography>

                            <Typography
                                noWrap
                                sx={{
                                    px: 1.25,
                                    fontSize: 13,
                                    color: isDark ? alpha("#ffffff", 0.72) : "#535862",
                                }}
                            >
                                {stripHtml(item.description || "-")}
                            </Typography>

                            <Box sx={{ display: "grid", placeItems: "center" }}>
                                <Checkbox
                                    checked={draftIds.includes(item.id)}
                                    onChange={() => toggleIssue(item.id)}
                                    size="small"
                                    sx={{
                                        p: 0,
                                        color: "#d0d5dd",
                                        "&.Mui-checked": {
                                            color: "#1a64a8",
                                        },
                                    }}
                                />
                            </Box>
                        </Box>
                    ))}
            </Box>

            <Box
                sx={{
                    mt: 1.5,
                    display: "flex",
                    alignItems: "center",
                    justifyContent: "flex-end",
                    gap: 2,
                }}
            >
                <ButtonBase onClick={handleSelectAll} sx={{ height: 36, px: 1 }}>
                    <Typography
                        sx={{
                            color: "#1a64a8",
                            fontSize: 13,
                            fontWeight: 600,
                            textDecoration: "underline",
                        }}
                    >
                        Select All
                    </Typography>
                </ButtonBase>

                <Button
                    variant="contained"
                    onClick={() => onConfirm(draftIds)}
                    disabled={draftIds.length === 0}
                    sx={{
                        height: 40,
                        minWidth: 150,
                        borderRadius: "6px",
                        bgcolor: "#1a64a8",
                        boxShadow: "none",
                        textTransform: "none",
                        fontSize: 13,
                        fontWeight: 700,
                        "&:hover": {
                            bgcolor: "#15548e",
                            boxShadow: "none",
                        },
                    }}
                >
                    Confirm
                </Button>
            </Box>
        </Popover>
    );
}

function SelectedIssueCard({
    issue,
    onRemove,
}: {
    issue: CreateIssue;
    onRemove: () => void;
}) {
    const theme = useTheme();
    const isDark = theme.palette.mode === "dark";

    return (
        <Box
            sx={{
                p: 1.5,
                borderRadius: "6px",
                border: `1px solid ${isDark ? alpha("#ffffff", 0.1) : "#e9eaeb"}`,
                backgroundColor: isDark ? alpha("#ffffff", 0.04) : "#ffffff",
                display: "flex",
                alignItems: "flex-start",
                justifyContent: "space-between",
                gap: 1.5,
            }}
        >
            <Box sx={{ minWidth: 0, flex: 1 }}>
                <Typography noWrap sx={{ fontSize: 14, fontWeight: 700 }}>
                    {stripHtml(issue.issue)}
                </Typography>

                <Box
                    sx={{
                        mt: 0.5,
                        color: "#717680",
                        fontSize: 13,
                        lineHeight: "22px",

                        "& p": {
                            margin: 0,
                        },

                        "& ol, & ul": {
                            margin: 0,
                            paddingLeft: "22px",
                        },

                        "& li": {
                            margin: 0,
                        },

                        "& strong": {
                            fontWeight: 700,
                        },

                        "& u": {
                            textDecoration: "underline",
                        },

                        "& em": {
                            fontStyle: "italic",
                        },
                    }}
                    dangerouslySetInnerHTML={{
                        __html: issue.description || "-",
                    }}
                />
            </Box>

            <ButtonBase
                onClick={onRemove}
                sx={{
                    width: 26,
                    height: 26,
                    borderRadius: "50%",
                    color: "#a4a7ae",
                    flexShrink: 0,
                    fontSize: 20,
                }}
            >
                ×
            </ButtonBase>
        </Box>
    );
}

export function MeetingRequestCreate({
    language = "km",
    onBack,
    mode = "create",
    editRow = null,
    onSubmit,
}: MeetingRequestCreateProps) {
    const theme = useTheme();
    const isDark = theme.palette.mode === "dark";
    const issueSelectRef = useRef<HTMLDivElement | null>(null);
    const issueIdsRef = useRef<number[]>([]);

    const [title, setTitle] = useState("");
    const [description, setDescription] = useState("");

    const [agencies, setAgencies] = useState<ApiGovernmentAgency[]>([]);
    const [issues, setIssues] = useState<ApiIssue[]>([]);

    const [loadingAgencies, setLoadingAgencies] = useState(false);
    const [loadingIssues, setLoadingIssues] = useState(false);

    const [firstAgencyId, setFirstAgencyId] = useState<number | "">("");
    const [secondAgencyId, setSecondAgencyId] = useState<number | "">("");
    const [thirdAgencyId, setThirdAgencyId] = useState<number | "">("");
    const [fourthAgencyId, setFourthAgencyId] = useState<number | "">("");
    const [fifthAgencyId, setFifthAgencyId] = useState<number | "">("");

    const [issueAnchorEl, setIssueAnchorEl] = useState<HTMLElement | null>(null);
    const [addIssueOpen, setAddIssueOpen] = useState(false);

    const [requestLetterFile, setRequestLetterFile] = useState<File | null>(null);
    const [requestLetterPath, setRequestLetterPath] = useState<string>("");

    const [submittingRequest, setSubmittingRequest] = useState(false);
    const [submitError, setSubmitError] = useState<string | null>(null);
    const [sendConfirmOpen, setSendConfirmOpen] = useState(false);

    const [selectedIssueIds, setSelectedIssueIds] = useState<number[]>([]);

    useEffect(() => {
        issueIdsRef.current = issues.map((issue) => issue.id);
    }, [issues]);

    useEffect(() => {
        let active = true;

        async function fetchFormData() {
            try {
                setLoadingAgencies(true);
                setLoadingIssues(true);
                setSubmitError(null);

                const [agencyResult, issueResult, primaryGovernment] =
                    await Promise.all([
                        meetingRequestService.getGovernmentAgencies().catch(() => []),
                        meetingRequestService.getWorkingGroupIssues().catch(() => []),
                        meetingRequestService.getMyPrimaryGovernment().catch(() => null),
                    ]);

                const defaultGovernmentAgency =
                    primaryGovernment?.governmentAgency || null;

                const defaultGovernmentAgencyId = defaultGovernmentAgency?.id || "";

                const safeAgencyResult = mergeUniqueAgencies(
                    agencyResult,
                    defaultGovernmentAgency,
                );

                if (!active) return;

                setAgencies(safeAgencyResult);
                setIssues(issueResult);

                if (mode !== "edit" || !editRow?.id) {
                    setTitle("");
                    setDescription("");
                    setFirstAgencyId(defaultGovernmentAgencyId);
                    setSecondAgencyId("");
                    setThirdAgencyId("");
                    setFourthAgencyId("");
                    setFifthAgencyId("");
                    setSelectedIssueIds([]);
                    setRequestLetterPath("");
                    setRequestLetterFile(null);
                    return;
                }

                const rowStatus = String(editRow.meetingStatus || "").toLowerCase();
                const isDraftedRow =
                    rowStatus === "drafted" ||
                    rowStatus.includes("draft") ||
                    rowStatus.includes("គ្រោង");

                if (isDraftedRow) {
                    const rowData = editRow as MeetingRequestRow & {
                        title?: string;
                        meetingDescription?: string;
                        description?: string;
                        meetingRequest?: string;
                        meetingRequestLetter?: string;
                        governmentAgencyId?: number | null;
                        issueIds?: number[];
                        issues?: ApiIssue[];
                        rawIssues?: ApiIssue[];
                    };

                    const draftIssues = rowData.rawIssues || rowData.issues || [];
                    const draftIssueIds =
                        rowData.issueIds || draftIssues.map((issue) => issue.id);

                    const mergedIssues = [
                        ...draftIssues,
                        ...issueResult.filter(
                            (item) =>
                                !draftIssues.some(
                                    (draftIssue) => draftIssue.id === item.id,
                                ),
                        ),
                    ];

                    setIssues(mergedIssues);
                    setTitle(rowData.title || "");
                    setDescription(
                        rowData.description ||
                            rowData.meetingDescription ||
                            "",
                    );

                    setFirstAgencyId(
                        rowData.governmentAgencyId || defaultGovernmentAgencyId,
                    );
                    setSecondAgencyId("");
                    setThirdAgencyId("");
                    setFourthAgencyId("");
                    setFifthAgencyId("");

                    setSelectedIssueIds(draftIssueIds);
                    setRequestLetterPath(
                        rowData.meetingRequestLetter ||
                            rowData.meetingRequest ||
                            "",
                    );
                    setRequestLetterFile(null);
                    setSubmitError(null);
                    return;
                }

                const detail = await meetingRequestService.getById(Number(editRow.id));

                if (!active) return;

                setTitle(detail.title || "");
                setDescription(detail.description || "");

                const detailIssues = detail.issues || [];
                const mergedIssues = [
                    ...detailIssues,
                    ...issueResult.filter(
                        (item) =>
                            !detailIssues.some((detailItem) => detailItem.id === item.id),
                    ),
                ];

                setIssues(mergedIssues);

                const agencyIds =
                    detail.governmentAgencies?.map((agency) => agency.stakeholderId) ||
                    [];

                setFirstAgencyId(agencyIds[0] || defaultGovernmentAgencyId);
                setSecondAgencyId(agencyIds[1] || "");
                setThirdAgencyId(agencyIds[2] || "");
                setFourthAgencyId(agencyIds[3] || "");
                setFifthAgencyId(agencyIds[4] || "");

                setSelectedIssueIds(detailIssues.map((issue) => issue.id));
                setRequestLetterPath(detail.meetingRequestLetter || "");
                setRequestLetterFile(null);
            } catch (error: unknown) {
                const message =
                    error instanceof Error
                        ? error.message
                        : "Failed to load meeting request data";

                setSubmitError(message);
            } finally {
                if (active) {
                    setLoadingAgencies(false);
                    setLoadingIssues(false);
                }
            }
        }

        fetchFormData();

        return () => {
            active = false;
        };
    }, [mode, editRow]);

    const selectedAgencyIds = useMemo(() => {
        return [
            firstAgencyId,
            secondAgencyId,
            thirdAgencyId,
            fourthAgencyId,
            fifthAgencyId,
        ].filter((id): id is number => typeof id === "number");
    }, [
        firstAgencyId,
        secondAgencyId,
        thirdAgencyId,
        fourthAgencyId,
        fifthAgencyId,
    ]);

    function getAvailableAgencies(currentValue: number | "") {
        return agencies.filter((agency) => {
            if (agency.id === currentValue) return true;
            return !selectedAgencyIds.includes(agency.id);
        });
    }

    const selectedIssues = useMemo(() => {
        return issues
            .filter((issue) => selectedIssueIds.includes(issue.id))
            .map(apiIssueToCreateIssue);
    }, [issues, selectedIssueIds]);

    function validateBeforeSubmit() {
        if (!title.trim()) {
            setSubmitError("Please enter title");
            return false;
        }

        if (!firstAgencyId) {
            setSubmitError("Please select Government Agency");
            return false;
        }

        if (!description.trim()) {
            setSubmitError("Please enter description");
            return false;
        }

        if (selectedAgencyIds.length === 0) {
            setSubmitError("Please select at least one agency");
            return false;
        }

        if (selectedIssueIds.length === 0) {
            setSubmitError("Please select at least one issue");
            return false;
        }

        if (!requestLetterFile && !requestLetterPath && mode === "create") {
            setSubmitError("Please upload Meeting Request Letter PDF");
            return false;
        }

        setSubmitError(null);
        return true;
    }

    function handleSendClick() {
        if (submittingRequest) {
            return;
        }

        if (!validateBeforeSubmit()) {
            return;
        }

        setSendConfirmOpen(true);
    }

    async function handleSubmit(sendNow = false) {
        if (!validateBeforeSubmit()) {
            return;
        }

        if (submittingRequest) return;

        try {
            setSubmittingRequest(true);
            setSubmitError(null);

            const submittedIssueIds = [...selectedIssueIds];
            const submittedIssues = [...selectedIssues];

            const payload: CreateMeetingRequestPayload = {
                title: title.trim(),
                description: description.trim(),
                meetingRequestLetter: requestLetterFile || requestLetterPath || "",
                stakeholderIds: selectedAgencyIds,
                issueIds: selectedIssueIds,
            };

            const savedRequest =
                mode === "edit" && editRow?.id
                    ? await meetingRequestService.update(Number(editRow.id), payload)
                    : await meetingRequestService.create(payload);

            // The meeting request is saved at this point. If the send step then
            // fails we must still leave this form, otherwise the user retries
            // and a second meeting request gets created.
            let finalRequest = savedRequest;
            let sendFailed = false;

            if (sendNow) {
                try {
                    finalRequest = await meetingRequestService.sendRequest(
                        Number(savedRequest.id),
                    );
                } catch {
                    sendFailed = true;
                }
            }

            // After Send Request success, hide only the issues that were submitted.
            // New issues that were not selected/submitted stay in the Issue List.
            if (sendNow && !sendFailed) {
                setIssues((current: ApiIssue[]) =>
                    current.filter((issue) => !submittedIssueIds.includes(issue.id)),
                );
                setSelectedIssueIds([]);
            }

            const mainAgency =
                agencies.find((agency) => agency.id === firstAgencyId)?.name || "-";

            setSendConfirmOpen(false);

            onSubmit?.(
                {
                    id: String(finalRequest.id || editRow?.id || Date.now()),
                    title: title.trim(),
                    governmentAgency: mainAgency,
                    description: description.trim(),
                    issues: submittedIssues,
                    requestLetterFileName:
                        requestLetterFile?.name || requestLetterPath || undefined,
                },
                { sent: sendNow && !sendFailed, sendFailed },
            );

            onBack();
        } catch (error: unknown) {
            const message =
                error instanceof Error ? error.message : "Create meeting request failed";

            setSubmitError(message);
            setSendConfirmOpen(false);
        } finally {
            setSubmittingRequest(false);
        }
    }

    return (
        <Box
            sx={{
                width: "100%",
                maxWidth: "100%",
                minWidth: 0,
                color: theme.palette.text.primary,
            }}
        >
            <Box
                sx={{
                    display: "flex",
                    alignItems: "flex-start",
                    gap: { xs: 2, md: 4 },
                    flexWrap: "wrap",
                }}
            >
                <ButtonBase
                    onClick={onBack}
                    sx={{
                        mt: 1.25,
                        display: "flex",
                        alignItems: "center",
                        gap: 1,
                        color: isDark ? alpha("#ffffff", 0.65) : "#717680",
                    }}
                >
                    <Typography sx={{ fontSize: 18, lineHeight: 1 }}>‹</Typography>
                    <Typography sx={{ fontSize: 13, fontWeight: 500 }}>Back</Typography>
                </ButtonBase>

                <Box sx={{ flex: 1, minWidth: 0 }}>
                    <Typography
                        sx={{
                            color: isDark ? "#ffffff" : "#0a0a0a",
                            fontSize: { xs: 28, md: 32 },
                            fontWeight: 700,
                            lineHeight: 1.2,
                            fontFamily: getMeetingRequestFont(language),
                        }}
                    >
                        Meeting Requests
                    </Typography>

                    <Typography
                        sx={{
                            mt: 1.25,
                            color: isDark ? alpha("#ffffff", 0.65) : "#535862",
                            fontSize: 13,
                            fontWeight: 500,
                        }}
                    >
                        Meeting Requests /{" "}
                        {mode === "edit" ? "Edit Meeting Request" : "Add Meeting Request"}
                    </Typography>
                </Box>
            </Box>

            <Box
                sx={{
                    mt: 2.75,
                    width: "100%",
                    minWidth: 0,
                    p: { xs: 2, md: "22px" },
                    borderRadius: "12px",
                    backgroundColor: isDark ? "#101828" : "#ffffff",
                    border: `1px solid ${isDark ? alpha("#ffffff", 0.1) : "#f5f5f5"}`,
                    display: "flex",
                    flexDirection: "column",
                    gap: "22px",
                    boxSizing: "border-box",
                }}
            >
                <Box
                    sx={{
                        display: "grid",
                        gridTemplateColumns: { xs: "1fr", md: "1fr 1fr" },
                        gap: "22px",
                    }}
                >
                    <Box>
                        <FormLabel required>Title</FormLabel>

                        <TextField
                            fullWidth
                            value={title}
                            onChange={(event) => setTitle(event.target.value)}
                            placeholder="Write title"
                            size="small"
                            sx={{
                                "& .MuiOutlinedInput-root": {
                                    height: 50,
                                    borderRadius: "6px",
                                },
                                "& .MuiOutlinedInput-input": {
                                    fontSize: 13,
                                    px: "18px",
                                },
                                "& .MuiOutlinedInput-notchedOutline": {
                                    borderColor: "#e9eaeb",
                                },
                            }}
                        />
                    </Box>

                    <AgencySelectField
                        label="Government Agency"
                        required
                        value={firstAgencyId}
                        agencies={getAvailableAgencies(firstAgencyId)}
                        loading={loadingAgencies}
                        disabled
                        onChange={setFirstAgencyId}
                    />

                    <AgencySelectField
                        label="Second Agency"
                        value={secondAgencyId}
                        agencies={getAvailableAgencies(secondAgencyId)}
                        loading={loadingAgencies}
                        onChange={setSecondAgencyId}
                    />

                    <AgencySelectField
                        label="Third Agency"
                        value={thirdAgencyId}
                        agencies={getAvailableAgencies(thirdAgencyId)}
                        loading={loadingAgencies}
                        onChange={setThirdAgencyId}
                    />

                    <AgencySelectField
                        label="Fourth Agency"
                        value={fourthAgencyId}
                        agencies={getAvailableAgencies(fourthAgencyId)}
                        loading={loadingAgencies}
                        onChange={setFourthAgencyId}
                    />

                    <AgencySelectField
                        label="Fifth Agency"
                        value={fifthAgencyId}
                        agencies={getAvailableAgencies(fifthAgencyId)}
                        loading={loadingAgencies}
                        onChange={setFifthAgencyId}
                    />
                </Box>

                <Box>
                    <FormLabel required>Description of the WG Meeting Request</FormLabel>

                    <AppTextEditor
                        value={description}
                        onChange={setDescription}
                        placeholder="Write description ........."
                    />
                </Box>

                <Box>
                    <FormLabel required>Issue List</FormLabel>

                    <Box
                        sx={{
                            display: "flex",
                            flexDirection: { xs: "column", sm: "row" },
                            alignItems: { xs: "stretch", sm: "flex-end" },
                            gap: "22px",
                        }}
                    >
                        <Box sx={{ flex: 1, minWidth: 0 }} ref={issueSelectRef}>
                            <SelectLikeField
                                placeholder="Select Issue"
                                selectedText={
                                    selectedIssues.length > 0
                                        ? `${selectedIssues.length} issue selected`
                                        : undefined
                                }
                                onClick={() => setIssueAnchorEl(issueSelectRef.current)}
                            />
                        </Box>

                        <Button
                            variant="outlined"
                            onClick={() => setAddIssueOpen(true)}
                            startIcon={
                                <Box
                                    component="img"
                                    src="/images/meeting-request/add-issue-plus.svg"
                                    alt=""
                                    sx={{ width: 18, height: 18, display: "block" }}
                                />
                            }
                            sx={{
                                height: 50,
                                minWidth: { xs: 0, sm: 140 },
                                width: { xs: "100%", sm: "auto" },
                                borderRadius: "6px",
                                borderStyle: "dashed",
                                borderColor: "#e9eaeb",
                                bgcolor: "#fafafa",
                                color: "#717680",
                                fontSize: 13,
                                fontWeight: 600,
                                textTransform: "none",
                                px: "18px",
                                "&:hover": {
                                    borderStyle: "dashed",
                                    borderColor: "#d0d5dd",
                                    bgcolor: "#f5f5f5",
                                },
                            }}
                        >
                            Add Issue
                        </Button>
                    </Box>

                    {selectedIssues.length > 0 ? (
                        <Box
                            sx={{ mt: 1.5, display: "flex", flexDirection: "column", gap: 1 }}
                        >
                            {selectedIssues.map((issue) => (
                                <SelectedIssueCard
                                    key={issue.id}
                                    issue={issue}
                                    onRemove={() =>
                                        setSelectedIssueIds((current: number[]) =>
                                            current.filter((id) => id !== issue.id),
                                        )
                                    }
                                />
                            ))}
                        </Box>
                    ) : null}
                </Box>

                <Box>
                    <FormLabel required>Meeting Request Letter</FormLabel>

                    <UploadBox
                        compact={Boolean(requestLetterFile || requestLetterPath)}
                        file={requestLetterFile}
                        initialFileName={requestLetterPath || undefined}
                        fileLabel="Request Doc"
                        onFileChange={setRequestLetterFile}
                    />
                </Box>

                {submitError ? (
                    <Typography sx={{ color: "#d92d20", fontSize: 13 }}>
                        {submitError}
                    </Typography>
                ) : null}

                <Box
                    sx={{
                        display: "flex",
                        flexDirection: { xs: "column", sm: "row" },
                        justifyContent: "flex-end",
                        gap: "22px",
                    }}
                >
                    <Button
                        variant="contained"
                        onClick={() => handleSubmit(false)}
                        disabled={submittingRequest}
                        sx={{
                            height: 44,
                            width: { xs: "100%", sm: 150 },
                            borderRadius: "6px",
                            bgcolor: "#a4a7ae",
                            color: "#ffffff",
                            boxShadow: "none",
                            fontSize: 13,
                            fontWeight: 500,
                            textTransform: "none",
                            "&:hover": {
                                bgcolor: "#717680",
                                boxShadow: "none",
                            },
                        }}
                    >
                        {submittingRequest ? "Saving..." : "Draft"}
                    </Button>

                    <Button
                        variant="contained"
                        onClick={handleSendClick}
                        disabled={submittingRequest}
                        sx={{
                            height: 44,
                            width: { xs: "100%", sm: 150 },
                            borderRadius: "6px",
                            bgcolor: "#717680",
                            color: "#ffffff",
                            boxShadow: "none",
                            fontSize: 13,
                            fontWeight: 500,
                            textTransform: "none",
                            "&:hover": {
                                bgcolor: "#535862",
                                boxShadow: "none",
                            },
                            "&.Mui-disabled": {
                                bgcolor: "#d0d5dd",
                                color: "#ffffff",
                            },
                        }}
                    >
                        {submittingRequest ? "Sending..." : "Send Request"}
                    </Button>
                </Box>
            </Box>

            <AlertDialog
                open={sendConfirmOpen}
                title="Send Request"
                description="Do you want to send this meeting request?"
                confirmLabel="Confirm"
                cancelLabel="Cancel"
                loading={submittingRequest}
                onConfirm={() => void handleSubmit(true)}
                onCancel={() => {
                    if (!submittingRequest) {
                        setSendConfirmOpen(false);
                    }
                }}
            />

            <IssueSelectorPopover
                key={`${issueAnchorEl ? "open" : "closed"}-${selectedIssueIds.join("-")}-${issues.length}`}
                anchorEl={issueAnchorEl}
                issues={issues}
                selectedIds={selectedIssueIds}
                loading={loadingIssues}
                onClose={() => setIssueAnchorEl(null)}
                onConfirm={(ids) => {
                    setSelectedIssueIds(ids);
                    setIssueAnchorEl(null);
                }}
            />

            <CreateIssueDialog
                open={addIssueOpen}
                onClose={() => setAddIssueOpen(false)}
                onCreated={() => {
                    void (async () => {
                        const previousIds = new Set(issueIdsRef.current);
                        const issueResult = await meetingRequestService
                            .getWorkingGroupIssues()
                            .catch(() => [] as ApiIssue[]);

                        setIssues(issueResult);

                        const newIds = issueResult
                            .filter((issue) => !previousIds.has(issue.id))
                            .map((issue) => issue.id);

                        if (newIds.length === 0) return;

                        setSelectedIssueIds((current) =>
                            Array.from(new Set([...newIds, ...current])),
                        );
                    })();
                }}
            />
        </Box>
    );
}