"use client";

import React, {
    CSSProperties,
    DetailedHTMLProps,
    HTMLAttributes,
    useEffect,
    useRef,
    useState,
} from "react";
import Paper from "@mui/material/Paper";
import Table from "@mui/material/Table";
import TableBody from "@mui/material/TableBody";
import TableCell from "@mui/material/TableCell";
import TableContainer from "@mui/material/TableContainer";
import TableHead from "@mui/material/TableHead";
import TablePagination from "@mui/material/TablePagination";
import TableRow from "@mui/material/TableRow";
import IconButton from "@mui/material/IconButton";
import EditIcon from "@mui/icons-material/Edit";
import SaveIcon from "@mui/icons-material/Save";
import CancelIcon from "@mui/icons-material/Close";
import DeleteIcon from "@mui/icons-material/Delete";
import TextField from "@mui/material/TextField";
import MultiSelect from "@/components/SearchBox/MultiSelect";
import { Collapse, Typography } from "@mui/material";
import BomMaterialTable from "./BomMaterialTable";
import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown";
import KeyboardArrowUpIcon from "@mui/icons-material/KeyboardArrowUp";
import { decimalFormatter, integerFormatter } from "@/app/utils/formatUtil";
import PlayCircleOutlineIcon from "@mui/icons-material/PlayCircleOutline";
import { useTranslation } from "react-i18next";
import {
    DetailedProdScheduleLineResult,
    RoughProdScheduleLineBomMaterialResult,
    RoughProdScheduleLineResultByFg,
    RoughProdScheduleResult,
    ScheduleType,
} from "@/app/api/scheduling";
import { defaultPagingController } from "../SearchResults/SearchResults";
import { useFormContext } from "react-hook-form";

export interface ResultWithId {
    id: string | number;
    // id: number;
}

interface BaseColumn<T extends ResultWithId> {
    field: keyof T;
    label: string;
    type: string;
    options?: T[];
    renderCell?: (params: T) => React.ReactNode;
    style?: Partial<HTMLElement["style"]> & {
        [propName: string]: string;
    } & CSSProperties;
}

interface ColumnWithAction<T extends ResultWithId> extends BaseColumn<T> {
    onClick: (item: T) => void;
    buttonIcon: React.ReactNode;
    buttonColor?: "inherit" | "default" | "primary" | "secondary";
}

export type Column<T extends ResultWithId> =
    | BaseColumn<T>
    | ColumnWithAction<T>;

interface Props<T extends ResultWithId> {
    index?: number;
    items: T[];
    columns: Column<T>[];
    noWrapper?: boolean;
    setPagingController?: (value: {
        pageNum: number;
        pageSize: number;
        totalCount: number;
        index?: number;
    }) => void;
    pagingController?: { pageNum: number; pageSize: number; totalCount: number };
    isAutoPaging: boolean;
    isEdit: boolean;
    isEditable: boolean;
    hasCollapse: boolean;
    type: ScheduleType;
    onReleaseClick?: (item: T) => void;
    onEditClick?: (rowId: number) => void;
    handleEditChange?: (rowId: number, fieldName: keyof T, newValue: number | string) => void;
    onSaveClick?: (item: T) => void;
    onCancelClick?: (rowId: number) => void;
}

function ScheduleTable<T extends ResultWithId>({
    type,
    index = 7,
    items,
    columns,
    noWrapper,
    pagingController = undefined,
    setPagingController = undefined,
    isAutoPaging = true,
    isEdit = false,
    isEditable = true,
    hasCollapse = false,
    onReleaseClick = undefined,
    onEditClick = undefined,
    handleEditChange = undefined,
    onSaveClick = undefined,
    onCancelClick = undefined,
}: Props<T>) {
    const [page, setPage] = useState(0);
    const [rowsPerPage, setRowsPerPage] = useState(10);
    const [editingRowId, setEditingRowId] = useState<number | null>(null);
    const [editedItems, setEditedItems] = useState<T[]>(items);
    const { t } = useTranslation("schedule");
    console.log(items)

    useEffect(() => {
        setEditedItems(items);
    }, [items]);

    const handleChangePage = (_event: unknown, newPage: number) => {
        setPage(newPage);
        if (setPagingController && pagingController) {
            setPagingController({
                ...pagingController,
                pageNum: newPage + 1,
                index: index ?? -1,
            });
        }
    };

    const handleChangeRowsPerPage = (
        event: React.ChangeEvent<HTMLInputElement>,
    ) => {
        setRowsPerPage(+event.target.value);
        setPage(0);
        if (setPagingController && pagingController) {
            setPagingController({
                ...pagingController,
                pageSize: +event.target.value,
                pageNum: 1,
                index: index,
            });
        }
    };

    const handleEditClick = (id: number) => {
        setEditingRowId(id);
        if (onEditClick) {
            onEditClick(id)
        }
    };

    const handleSaveClick = (item: T) => {
        setEditingRowId(null);
        // Call API or any save logic here
        if (onSaveClick) {
            onSaveClick(item)
        } else {
            setEditedItems((prev) =>
                prev.map((row) => (row.id === item.id ? { ...row } : row)),
            );
        }
    };

    const handleReleaseClick = (item: T) => {
        if (onReleaseClick) {
            onReleaseClick(item)
        }
    }

    const handleInputChange = (
        id: number,
        field: keyof T,
        // value: string | number[],
        value: string | number,
    ) => {
        if (handleEditChange) {
            handleEditChange(id, field, value)
        } else {
            setEditedItems((prev) =>
                prev.map((item) => (item.id === id ? { ...item, [field]: value } : item)),
            );
        }
    };

    const handleDeleteClick = (id: number) => {
        // Implement delete logic here
        setEditedItems((prev) => prev.filter((item) => item.id !== id));
    };

    const handleCancelClick = (id: number) => {
        if (onCancelClick) {
            onCancelClick(id)
        }

        setEditingRowId(null)
    }

    useEffect(() => {
        console.log("[debug] isEdit in table", isEdit);
        //TODO: switch all record to not in edit mode and save the changes
        if (!isEdit) {
            editedItems?.forEach((item) => {
                // Call save logic here
                // console.log("Saving item:", item);
                // Reset editing state if needed
            });

            setEditingRowId(null);
        }
    }, [isEdit]);

    function isRoughType(type: ScheduleType): type is "rough" {
        return type === "rough";
    }

    function isDetailedType(type: ScheduleType): type is "detailed" {
        return type === "detailed";
    }

    function Row(props: { row: T }) {
        const { row } = props;
        const [open, setOpen] = useState(false);
        // console.log(row)
        return (
            <>
                <TableRow hover tabIndex={-1} key={row.id}>
                    {isDetailedType(type) && (
                        <TableCell>
                            <IconButton
                                color="primary"
                                disabled={
                                    // !(row as unknown as DetailedProdScheduleLineResult).bomMaterials.every(ele => (ele.availableQty ?? 0) >= (ele.demandQty ?? 0)) 
                                    // || 
                                    editingRowId === row.id
                                    || (row as unknown as DetailedProdScheduleLineResult).approved}
                                onClick={() => handleReleaseClick(row)}
                            >
                                <PlayCircleOutlineIcon />
                            </IconButton>
                        </TableCell>
                    )}
                    {(isEditable || hasCollapse) && (
                        <TableCell>
                            {editingRowId === row.id ? (
                                <>
                                    {isDetailedType(type) && isEditable && (
                                        <IconButton
                                            disabled={!isEdit}
                                            onClick={() => handleSaveClick(row)}
                                        >
                                            <SaveIcon />
                                        </IconButton>
                                    )}
                                    {isDetailedType(type) && isEditable && (
                                        <IconButton
                                            disabled={!isEdit}
                                            onClick={() => handleCancelClick(row.id as number)}
                                        >
                                            <CancelIcon />
                                        </IconButton>
                                    )}
                                    {hasCollapse && (
                                        <IconButton
                                            aria-label="expand row"
                                            size="small"
                                            onClick={() => setOpen(!open)}
                                        >
                                            {open ? (
                                                <KeyboardArrowUpIcon />
                                            ) : (
                                                <KeyboardArrowDownIcon />
                                            )}
                                            <Typography>{t("View BoM")}</Typography>
                                        </IconButton>
                                    )}
                                </>
                            ) : (
                                <>
                                    {isDetailedType(type) && isEditable && (
                                        <IconButton
                                            disabled={!isEdit || (row as unknown as DetailedProdScheduleLineResult).approved}
                                            onClick={() => handleEditClick(row.id as number)}
                                        >
                                            <EditIcon />
                                        </IconButton>
                                    )}
                                    {/* {isDetailedType(type) && isEditable && (
                                        <IconButton
                                            disabled={!isEdit}
                                            onClick={() => handleDeleteClick(row.id as number)}
                                        >
                                            <DeleteIcon />
                                        </IconButton>
                                    )} */}
                                    {hasCollapse && (
                                        <IconButton
                                            aria-label="expand row"
                                            size="small"
                                            onClick={() => setOpen(!open)}
                                        >
                                            {open ? (
                                                <KeyboardArrowUpIcon />
                                            ) : (
                                                <KeyboardArrowDownIcon />
                                            )}
                                            <Typography>{t("View BoM")}</Typography>
                                        </IconButton>
                                    )}
                                </>
                            )}
                        </TableCell>
                    )}
                    {columns.map((column, idx) => {
                        const columnName = column.field;
                        return (
                            <TableCell key={`${columnName.toString()}-${idx}`}>
                                {editingRowId === row.id ? (
                                    (() => {
                                        switch (column.type) {
                                            case "input":
                                                return (
                                                    <TextField
                                                        hiddenLabel={true}
                                                        fullWidth
                                                        defaultValue={row[columnName] as string}
                                                        onChange={(e) =>
                                                            handleInputChange(
                                                                row.id as number,
                                                                columnName,
                                                                e.target.value,
                                                            )
                                                        }
                                                    />
                                                );
                                            case "input-number":
                                                return (
                                                    <TextField
                                                        type="number"
                                                        hiddenLabel={true}
                                                        fullWidth
                                                        defaultValue={row[columnName] as string}
                                                        onChange={(e) => {
                                                            handleInputChange(
                                                                row.id as number,
                                                                columnName,
                                                                e.target.value,
                                                            )
                                                        }}
                                                    // onChange={(e) =>
                                                    //     handleInputChange(
                                                    //         row.id as number,
                                                    //         columnName,
                                                    //         e.target.value,
                                                    //     )
                                                    // }
                                                    />
                                                );
                                            // case 'multi-select':
                                            //     //TODO: May need update if use
                                            //     return (
                                            //         <MultiSelect
                                            //             //label={column.label}
                                            //             options={column.options ?? []}
                                            //             selectedValues={[]}
                                            //             onChange={(selectedValues) => handleInputChange(row.id as number, columnName, selectedValues)}
                                            //         />
                                            //     );
                                            case "read-only":
                                                return column.renderCell ? (
                                                    <div style={column.style}>{column.renderCell(row)}</div>
                                                ) : <span>{row[columnName] as string}</span>;
                                            default:
                                                return null; // Handle any default case if needed
                                        }
                                    })()
                                ) : column.renderCell ? (
                                    <div style={column.style}>{column.renderCell(row)}</div>
                                ) : (
                                    <div style={column.style}>
                                        <span
                                            onDoubleClick={() =>
                                                isEdit && handleEditClick(row.id as number)
                                            }
                                        >
                                            {row[columnName] as string}
                                        </span>
                                    </div>
                                )}
                            </TableCell>
                        );
                    })}
                </TableRow>
                <TableRow>
                    {hasCollapse && (
                        <TableCell style={{ paddingBottom: 0, paddingTop: 0 }} colSpan={6}>
                            <Collapse in={open} timeout="auto" unmountOnExit>
                                <Table>
                                    <TableBody>
                                        <TableRow>
                                            <TableCell>
                                                <BomMaterialTable
                                                    type={type}
                                                    bomMaterial={
                                                        isDetailedType(type) ? (row as unknown as RoughProdScheduleLineResultByFg).bomMaterials
                                                            : (row as unknown as DetailedProdScheduleLineResult).bomMaterials
                                                    }
                                                />
                                            </TableCell>
                                        </TableRow>
                                    </TableBody>
                                </Table>
                            </Collapse>
                        </TableCell>
                    )}
                </TableRow>
            </>
        );
    }

    const table = (
        <>
            <TableContainer sx={{ maxHeight: 440 }}>
                <Table stickyHeader>
                    <TableHead>
                        <TableRow>
                            {isDetailedType(type) && <TableCell>{t("Release")}</TableCell>}
                            {(isEditable || hasCollapse) && (
                                <TableCell>{t("Actions")}</TableCell>
                            )}{" "}
                            {/* Action Column Header */}
                            {columns.map((column, idx) => (
                                <TableCell
                                    style={column.style}
                                    key={`${column.field.toString()}${idx}`}
                                >
                                    {column.label}
                                </TableCell>
                            ))}
                        </TableRow>
                    </TableHead>
                    <TableBody>
                        {/* {(isAutoPaging ? editedItems.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) : editedItems).map((item) => ( */}
                        {editedItems
                            ?.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
                            ?.map((item) => <Row key={item.id} row={item} />)}
                    </TableBody>
                </Table>
            </TableContainer>
            <TablePagination
                rowsPerPageOptions={[10, 25, 100]}
                component="div"
                // count={pagingController.totalCount === 0 ? editedItems.length : pagingController.totalCount}
                count={editedItems?.length ?? 0}
                rowsPerPage={rowsPerPage}
                page={page}
                onPageChange={handleChangePage}
                onRowsPerPageChange={handleChangeRowsPerPage}
            />
        </>
    );

    return noWrapper ? table : <Paper sx={{ overflow: "hidden" }}>{table}</Paper>;
}

export default ScheduleTable;
