"use client";

import React, { useRef, useState, useEffect, useMemo } from "react";
import { AgGridReact } from "ag-grid-react";
import {
    AllCommunityModule,
    themeBalham,
    ColDef,
    CellValueChangedEvent,
} from "ag-grid-community";
import { toast } from "react-toastify";
import { AnimatePresence, motion } from "framer-motion";
import Button from "@/_components/Button";
import { RowDataType, ErrorType } from "@/_types/Types";



type GridProps = {
    rowData: RowDataType[];
    setActiveStep: (data: number) => void;
};

const Grid = ({ rowData, setActiveStep }: GridProps) => {
    const gridRef = useRef<null|AgGridReact<RowDataType>>(null);
    const hasShownToast = useRef(false);
    const [errors, setErrors] = useState<ErrorType[]>([]);
    const columnDefs: ColDef<RowDataType>[] = [
        {
            field: "firstName",
            cellEditor: "agTextCellEditor",
            cellEditorParams: {
                maxLength: 20,
            },
            cellClassRules: {
                "invalid-cell": (params) => !params.value || params.value.trim() === "",
            },
        },
        {
            field: "lastName",
            cellEditor: "agTextCellEditor",
            cellEditorParams: {
                maxLength: 20,
            },
            cellClassRules: {
                "invalid-cell": (params) => !params.value || params.value.trim() === "",
            },
        },
        {
            field: "company",
            cellEditor: "agTextCellEditor",
            cellEditorParams: {
                maxLength: 20,
            },
            cellClassRules: {
                "invalid-cell": (params) => !params.value || params.value.trim() === "",
            },
        },
        {
            field: "phone",
            cellEditor: "agTextCellEditor",
            cellEditorParams: {
                maxLength: 20,
            },
            cellClassRules: {
                "invalid-cell": (params) => !params.value || params.value.trim() === "",
            },
        },
        {
            field: "email",
            cellEditor: "agTextCellEditor",
            cellEditorParams: {
                maxLength: 20,
            },
            cellClassRules: {
                "invalid-cell": (params) => {
                    if (!params.value || params.value.trim() === "") return true;
                    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
                    return !emailRegex.test(params.value);
                },
            },
        },
    ];

    const defaultColDef = useMemo(() => {
        return {
            flex: 1,
            editable: true,
        };
    }, []);

    const validateInitialGridData = (data: RowDataType[]) => {
        const errorsArray: ErrorType[] = [];

        data.forEach((row, index) => {
            Object.entries(row).forEach(([key, value]) => {
                if (!value || value.trim() === "") {
                    errorsArray.push({
                        rowId: index + 1,
                        colId: key,
                        msg: `Field '${key}' is empty.`,
                    });
                }
            });

            const email = row.email;
            const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
            if (email && !emailRegex.test(email)) {
                errorsArray.push({
                    rowId: index + 1,
                    colId: "email",
                    msg: `Field email, '${email}' is not a valid email.`,
                });
            }
        });

        return errorsArray;
    };

    const validateRow = (rowData: RowDataType, rowId: number): ErrorType[] => {
        const errors: ErrorType[] = [];
        if (rowId === null) return [];

        for (const key in rowData) {
            const value = rowData[key];

            if (!value || value.toString().trim() === "") {
                errors.push({
                    rowId: rowId + 1,
                    colId: key,
                    msg: `Field '${key}' is empty.`,
                });
            }

            if (key.toLowerCase().includes("email")) {
                const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
                if (!emailRegex.test(value)) {
                    errors.push({
                        rowId: rowId + 1,
                        colId: key,
                        msg: `Field email, '${value}' is not a valid email.`,
                    });
                }
            }
        }

        return errors;
    };

    const handleCellValueChanged = (params: CellValueChangedEvent) => {
        const updatedRow = params.data;
        const updatedRowIndex = params.rowIndex;
        if (updatedRowIndex === null) return;

        const fieldErrors = validateRow(updatedRow, updatedRowIndex);

        setErrors((prevErrors) => {
            const filtered = prevErrors.filter(
                (err) => err.rowId !== updatedRowIndex + 1
            );
            return [...filtered, ...fieldErrors];
        });

        gridRef.current?.api.refreshCells({ force: true });
    };

    useEffect(() => {
        if (rowData && rowData.length > 0) {
            const newErrors = validateInitialGridData(rowData);
            if (newErrors.length > 0) {
                setErrors(newErrors);
                if (!hasShownToast.current) {
                    toast.error("Some fields need to be reviewed");
                    hasShownToast.current = true;
                }
            }
        }
    }, [rowData]);

    return (
        <div>
            <div
                className="p-8 mx-auto space-y-8 w-full"
                style={{ height: 400, width: "100%" }}
            >
                <AgGridReact
                    ref={gridRef}
                    theme={themeBalham}
                    rowData={rowData}
                    columnDefs={columnDefs}
                    defaultColDef={defaultColDef}
                    modules={[AllCommunityModule]}
                    invalidEditValueMode={"block"}
                    onCellValueChanged={handleCellValueChanged}
                />
            </div>

            <div className="text-center">
                <Button
                    disabled={errors.length > 0}
                    onClick={() => setActiveStep(2)}
                >
                    SUBMIT
                </Button>
            </div>
            {errors.length > 0 && (
                <ul role="list" className="divide-y divide-gray-100">
                    <AnimatePresence initial={false}>
                        {errors.map((error, i) => {
                            return (
                                <motion.li
                                    key={i}
                                    initial={{ opacity: 0, scale: 0 }}
                                    animate={{ opacity: 1, scale: 1 }}
                                    exit={{ opacity: 0, scale: 0 }}
                                    className="flex justify-between gap-x-6 border-red-500 border-1 p-2 my-2 bg-[#ffe5e5] rounded-sm"
                                >
                                    <div className="">
                                        <p className="text-sm/6 font-semibold text-gray-900">
                                            Row {error.rowId}
                                        </p>
                                    </div>
                                    <div className="">
                                        <p className="text-sm/6 text-gray-900">{error.msg}</p>
                                    </div>
                                </motion.li>
                            );
                        })}
                    </AnimatePresence>
                </ul>
            )}
        </div>
    );
};

export default Grid;
