import * as React from 'react';
import {
    Button,
} from '@mui/material';
import {
    DataGrid,
    GridActionsCellItem,
    GridRowEditStopReasons,
    GridRowModes,
    GridToolbarContainer
} from "@mui/x-data-grid";
import { DatePicker } from '@mui/x-date-pickers/DatePicker';
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
import dayjs from 'dayjs';
import EditIcon from '@mui/icons-material/Edit';
import DeleteIcon from '@mui/icons-material/DeleteOutlined';
import SaveIcon from '@mui/icons-material/Save';
import CancelIcon from '@mui/icons-material/Close';
import AddIcon from '@mui/icons-material/Add';
import axios from "axios";
import { apiPath } from "../../auth/utils";
import {
    GET_FORM_SIG_PAGE_LIST,
    UPDATE_FORM_SIG_PAGE_PATH,
} from "../../utils/ApiPathConst";
import {
    CustomNoRowsOverlay,
    GeneralConfirmWindow,
    notifyDeleteError,
    notifyDeleteSuccess,
    notifySaveSuccess,
    removeObjectWithId
} from "../../utils/CommonFunction";
import UploadContext from "../../components/UploadProvider";
import { LIONER_BUTTON_THEME } from "../../themes/colorConst";
import { ThemeProvider } from "@emotion/react";

const FORM_CODES = ['IDA', 'FNA', 'HSBCFIN', 'HSBCA31', 'MLB03S', 'MLFNA_EN', 'MLFNA_CHI', 'SLFNA_EN', 'SLFNA_CHI', 'SLAPP', 'SLGII'];
const SIG_TYPES = ['upload1', 'upload2'];
const ACTIONS = ['REPLACE', 'SKIP_AND_APPEND'];

let newRowId = -1;

function normalizeStartDate(value) {
    if (value == null || value === '') return '';
    if (dayjs.isDayjs(value)) return value.format('YYYY-MM-DD');
    const d = dayjs(value);
    return d.isValid() ? d.format('YYYY-MM-DD') : String(value);
}

function toDayjsOrNull(value) {
    if (value == null || value === '') return null;
    if (dayjs.isDayjs(value)) return value;
    if (typeof value === 'string') {
        const d = dayjs(value);
        return d.isValid() ? d : null;
    }
    if (Array.isArray(value) && value.length >= 3) {
        const y = value[0];
        const m = String(value[1]).padStart(2, '0');
        const d = dayjs(`${y}-${m}-${String(value[2]).padStart(2, '0')}`);
        return d.isValid() ? d : null;
    }
    if (typeof value === 'object' && value.year != null && value.month != null && value.day != null) {
        const d = dayjs(`${value.year}-${String(value.month).padStart(2, '0')}-${String(value.day).padStart(2, '0')}`);
        return d.isValid() ? d : null;
    }
    const d = dayjs(value);
    return d.isValid() ? d : null;
}

function formatStartDate(value) {
    const d = toDayjsOrNull(value);
    return d ? d.format('YYYY-MM-DD') : '';
}

function EditToolbar({ setRows, setRowModesModel }) {
    const handleClick = () => {
        const id = newRowId--;
        setRows((oldRows) => [
            {
                id,
                formCode: 'IDA',
                startDate: '2000-01-01',
                sigType: 'upload1',
                pageFrom: 1,
                pageTo: 1,
                action: 'REPLACE',
                isNew: true,
            },
            ...oldRows,
        ]);
        setRowModesModel((oldModel) => ({
            ...oldModel,
            [id]: { mode: GridRowModes.Edit, fieldToFocus: 'formCode' },
        }));
    };

    return (
        <GridToolbarContainer sx={{ ml: 1 }}>
            <Button color="primary" startIcon={<AddIcon />} onClick={handleClick}>
                Add Form Sig Page
            </Button>
        </GridToolbarContainer>
    );
}

export default function FormSigPageTable({ recordList }) {
    const [rows, setRows] = React.useState([]);
    const [rowModesModel, setRowModesModel] = React.useState({});
    const { setIsUploading } = React.useContext(UploadContext);
    const [isWindowOpen, setIsWindowOpen] = React.useState(false);
    const [selectedId, setSelectedId] = React.useState(null);
    const [paginationModel, setPaginationModel] = React.useState({ page: 0, pageSize: 10 });

    React.useEffect(() => {
        setPaginationModel({ page: 0, pageSize: 10 });
        setRows(recordList || []);
    }, [recordList]);

    const handleClose = () => setIsWindowOpen(false);

    const handleDeleteClick = (id) => () => {
        setIsWindowOpen(true);
        setSelectedId(id);
    };

    const updateData = () => {
        setIsUploading(true);
        axios
            .delete(`${apiPath}${GET_FORM_SIG_PAGE_LIST}/${selectedId}`)
            .then((response) => {
                if (response.status === 204) {
                    notifyDeleteSuccess();
                    setRows((prev) => removeObjectWithId(prev, selectedId));
                    setIsWindowOpen(false);
                }
                setIsUploading(false);
            })
            .catch((err) => {
                console.error(err);
                notifyDeleteError(err?.response?.data?.message || 'Delete failed');
                setIsUploading(false);
            });
    };

    const handleRowEditStop = (params, event) => {
        if (params.reason === GridRowEditStopReasons.rowFocusOut) {
            event.defaultMuiPrevented = true;
        }
    };

    const handleEditClick = (id) => () => {
        setRowModesModel((prev) => ({ ...prev, [id]: { mode: GridRowModes.Edit, fieldToFocus: 'formCode' } }));
    };

    const handleSaveClick = (id) => () => {
        setRowModesModel((prev) => ({ ...prev, [id]: { mode: GridRowModes.View } }));
    };

    const handleCancelClick = (id) => () => {
        setRowModesModel((prev => {
            const next = { ...prev, [id]: { mode: GridRowModes.View, ignoreModifications: true } };
            return next;
        }));
        const editedRow = rows.find((r) => r.id === id);
        if (editedRow?.isNew) {
            setRows((prev) => prev.filter((r) => r.id !== id));
        }
    };

    const processRowUpdate = (newRow) => {
        const isCreate = newRow.isNew === true || newRow.id == null || Number(newRow.id) <= 0;
        const payload = {
            formCode: newRow.formCode,
            startDate: normalizeStartDate(newRow.startDate),
            sigType: newRow.sigType,
            pageFrom: Number(newRow.pageFrom),
            pageTo: Number(newRow.pageTo),
            action: newRow.action,
        };
        if (!isCreate) payload.id = Number(newRow.id);

        return new Promise((resolve, reject) => {
            if (!payload.formCode || !payload.startDate || !payload.sigType ||
                payload.pageFrom == null || payload.pageTo == null || !payload.action) {
                reject(new Error('All fields are required'));
                return;
            }
            if (payload.pageFrom > payload.pageTo) {
                reject(new Error('pageFrom must be <= pageTo'));
                return;
            }
            setIsUploading(true);
            axios
                .post(`${apiPath}${UPDATE_FORM_SIG_PAGE_PATH}`, payload)
                .then((res) => {
                    const savedId = res.data?.id;
                    const updatedRow = { ...newRow, id: savedId != null ? savedId : newRow.id, isNew: false };
                    setRows((prev) => prev.map((r) => (r.id === newRow.id ? updatedRow : r)));
                    notifySaveSuccess();
                    setIsUploading(false);
                    resolve(updatedRow);
                })
                .catch((err) => {
                    setIsUploading(false);
                    notifyDeleteError(err?.response?.data?.message || 'Save failed');
                    reject(err);
                });
        });
    };

    const columns = [
        {
            field: 'actions',
            type: 'actions',
            headerName: 'Actions',
            width: 120,
            getActions: ({ id }) => {
                const isInEditMode = rowModesModel[id]?.mode === GridRowModes.Edit;
                if (isInEditMode) {
                    return [
                        <ThemeProvider key="cancel" theme={LIONER_BUTTON_THEME}>
                            <GridActionsCellItem icon={<CancelIcon />} label="Cancel" onClick={handleCancelClick(id)} color="delete" />,
                        </ThemeProvider>,
                        <ThemeProvider key="save" theme={LIONER_BUTTON_THEME}>
                            <GridActionsCellItem icon={<SaveIcon />} label="Save" onClick={handleSaveClick(id)} color="save" />,
                        </ThemeProvider>,
                    ];
                }
                return [
                    <ThemeProvider key="delete" theme={LIONER_BUTTON_THEME}>
                        <GridActionsCellItem icon={<DeleteIcon />} label="Delete" onClick={handleDeleteClick(id)} color="delete" />,
                    </ThemeProvider>,
                    <ThemeProvider key="edit" theme={LIONER_BUTTON_THEME}>
                        <GridActionsCellItem icon={<EditIcon />} label="Edit" onClick={handleEditClick(id)} color="edit" />,
                    </ThemeProvider>,
                ];
            },
        },
        {
            field: 'formCode',
            headerName: 'Form Code',
            width: 120,
            editable: true,
            type: 'singleSelect',
            valueOptions: FORM_CODES,
        },
        {
            field: 'startDate',
            headerName: 'Start Date',
            width: 140,
            editable: true,
            valueGetter: (params) => formatStartDate(params.row?.startDate),
            renderCell: (params) => formatStartDate(params.row?.startDate),
            renderEditCell: (params) => (
                <LocalizationProvider dateAdapter={AdapterDayjs}>
                    <DatePicker
                        value={toDayjsOrNull(params.row?.startDate)}
                        onChange={(d) =>
                            params.api.setEditCellValue({
                                id: params.id,
                                field: params.field,
                                value: d ? d.format('YYYY-MM-DD') : '',
                            })
                        }
                        slotProps={{ textField: { size: 'small', fullWidth: true } }}
                    />
                </LocalizationProvider>
            ),
        },
        {
            field: 'sigType',
            headerName: 'Sig Type',
            width: 90,
            editable: true,
            type: 'singleSelect',
            valueOptions: SIG_TYPES,
        },
        { field: 'pageFrom', headerName: 'Page From', type: 'number', width: 95, editable: true },
        { field: 'pageTo', headerName: 'Page To', type: 'number', width: 95, editable: true },
        {
            field: 'action',
            headerName: 'Action',
            width: 140,
            editable: true,
            type: 'singleSelect',
            valueOptions: ACTIONS,
        },
    ];

    return (
        <div style={{ width: '100%' }}>
            <DataGrid
                rows={rows}
                columns={columns}
                columnHeaderHeight={45}
                editMode="row"
                rowModesModel={rowModesModel}
                onRowModesModelChange={setRowModesModel}
                onRowEditStop={handleRowEditStop}
                processRowUpdate={processRowUpdate}
                onProcessRowUpdateError={(err) => notifyDeleteError(err?.message || 'Update failed')}
                getRowHeight={() => 'auto'}
                paginationModel={paginationModel}
                onPaginationModelChange={setPaginationModel}
                pageSizeOptions={[10, 25, 50]}
                slots={{
                    toolbar: EditToolbar,
                    noRowsOverlay: () => CustomNoRowsOverlay(),
                }}
                slotProps={{ toolbar: { setRows, setRowModesModel } }}
                autoHeight
            />
            <GeneralConfirmWindow
                isWindowOpen={isWindowOpen}
                title="Delete Form Sig Page"
                content="Are you sure you want to delete this record?"
                onNormalClose={handleClose}
                onConfirmClose={updateData}
            />
        </div>
    );
}
