import { React, useState } from "react";
import { DataTable } from "primereact/datatable";
import { Column } from "primereact/column";
import AuthenticatedLayout from "@/Layouts/AuthenticatedLayout";
import { Button } from "primereact/button";
import { InputText } from "primereact/inputtext";
import { Dialog } from "primereact/dialog";

import { useRef } from "react";
import { useForm, Controller, useFieldArray } from "react-hook-form";
import axios from "axios";
import { Toast } from "primereact/toast";
import { useEffect } from "react";
import { FilterMatchMode, FilterOperator } from "primereact/api";
import { ConfirmPopup, confirmPopup } from "primereact/confirmpopup";

import { authUser } from "@/Components/AuthProvider";
import { useContext } from "react";

import { AutoComplete } from "primereact/autocomplete";
import { Calendar } from "primereact/calendar";
import WarehouseDropdown from "@/Components/WarehouseDropdown";

function OpeningBalance({ auth }) {
    const { permission } = useContext(authUser);
    const [status, setStatus] = useState("create");
    const [visible, setVisible] = useState(false);
    const [id, setId] = useState();
    const formSubmit = useRef(null);
    const toast = useRef(null);
    const [customer, setCustomer] = useState([]);
    const [company, setCompany] = useState([]);

    const [filters, setFilters] = useState({
        global: { value: null, matchMode: FilterMatchMode.CONTAINS },
        name: { value: null, matchMode: FilterMatchMode.STARTS_WITH },
        type: { value: null, matchMode: FilterMatchMode.STARTS_WITH },
    });
    const [filters2, setFilters2] = useState({
        global: { value: null, matchMode: FilterMatchMode.CONTAINS },
        "client.name": { value: null, matchMode: FilterMatchMode.STARTS_WITH },
    });
    const [globalFilterValue, setGlobalFilterValue] = useState("");
    const [globalFilterValue2, setGlobalFilterValue2] = useState("");

    const [customerList, setCustoemrList] = useState([]);
    const [search, setSearchValue] = useState({
        company: "",
        customer: "",
    });

    const {
        register,
        control,
        handleSubmit,
        formState: { errors },
        setValue,
        watch,
        reset,
        clearErrors,
        setError,
    } = useForm({
        customer_id: "",
        list: [
            {
                supplier_id: "",
                supplier_info: "",
                opening_balance: "",
                opening_date: "",
            },
        ],
    });

    const { fields, append, prepend, remove } = useFieldArray({
        control,
        name: "list",
    });

    useEffect(() => {
        axios.get(route("customer.opening.view")).then((response) => {
            setCustoemrList(response.data.customers);
        });

        if (!permission.includes("customer_retailer_superAdmin_access")) {
            setValue("warehouse_id", auth.user.shop_id);
        }
    }, []);
    const getFormErrorMessageMultiple = (name, index = null) => {
        return errors["list"] &&
            errors["list"][index] &&
            errors["list"][index][name] ? (
            <small className="p-error ">
                {errors["list"][index][name]["message"]}
            </small>
        ) : (
            ""
        );
    };

    const getFormErrorMessageSingel = (name) => {
        return errors[name] ? (
            <small className="p-error ">{errors[name]["message"]}</small>
        ) : (
            ""
        );
    };

    {
        /* Table Data Search */
    }
    const onGlobalFilterChange = (e) => {
        const value = e.target.value;
        let _filters = { ...filters };

        _filters["global"].value = value;

        setFilters(_filters);
        setGlobalFilterValue(value);
    };
    const onGlobalFilterChange2 = (e) => {
        const value = e.target.value;
        let _filters = { ...filters2 };

        _filters["global"].value = value;

        setFilters2(_filters);
        setGlobalFilterValue2(value);
    };
    {
        /*Table Header*/
    }
    const TableHeader = () => {
        return (
            <div
                className={`w-100% flex ${
                    true ? "justify-between" : "justify-end"
                } `}
            >
                {permission.includes("customer_retailer_opening_create") && (
                    <Button
                        type="button"
                        icon={<span className="pi pi-plus text-sm pr-1" />}
                        label="Add"
                        onClick={() => {
                            setVisible(true);
                            setStatus("create");
                            setSearchValue({
                                company: "",
                                customer: "",
                            });
                            reset({
                                customer_id: "",
                                warehouse_id: watch("warehouse_id"),
                                list: [],
                            });
                        }}
                        className="p-button-success h-[41px]  text-[14px] "
                    />
                )}

                <span className="p-input-icon-left h-10 ">
                    <i className="pi pi-search" />
                    <InputText
                        className="h-[41px] w-48"
                        value={globalFilterValue2}
                        onChange={onGlobalFilterChange2}
                        placeholder="Search"
                    />
                </span>
            </div>
        );
    };

    const CompanyTableHeader = () => {
        return (
            <div className={`w-100% flex justify-end`}>
                <span className="p-input-icon-left h-10 ">
                    <i className="pi pi-search" />
                    <InputText
                        className="h-[41px] w-48"
                        value={globalFilterValue}
                        onChange={onGlobalFilterChange}
                        placeholder="Search"
                    />
                </span>
            </div>
        );
    };

    {
        /*Dilog Model Footer*/
    }
    const footerContent = (
        <div className="flex justify-end">
            <Button
                label="Cancel"
                icon="pi pi-times"
                onClick={() => {
                    setVisible(false);

                    reset({
                        shop_id: "",
                        warehouse_id: watch("warehouse_id"),
                        list: [],
                    });
                }}
                className="p-button-text w-13 text-sm"
            />
            <Button
                label="Save"
                type="submit"
                onClick={() => {
                    formSubmit.current.dispatchEvent(
                        new Event("submit", { bubbles: true })
                    );
                }}
                icon="pi pi-check"
                className="p-button-text w-13 text-sm"
            />
        </div>
    );

    // Store Data
    const StoreData = (data) => {
        if (data.list.length != 0) {
            axios
                .post(route("customer-opening.store"), data)
                .then((response) => {
                    toast.current.show({
                        severity: "info",
                        summary: "Confirmed",
                        detail: response.data.success,
                        life: 3000,
                    });
                    setCustoemrList(response.data.customers);
                    setVisible(false);

                    reset({
                        warehouse_id: watch("warehouse_id"),
                        shop_id: "",
                        list: [],
                    });
                })
                .catch((error) => {
                    let errors = error.response.data.errors;
                    Object.keys(errors).forEach((field) => {
                        setError(field, {
                            type: "manual",
                            message: errors[field][0],
                        });
                    });
                });
        } else {
            toast.current.show({
                severity: "warn",
                summary: "Rejected",
                detail: "Must need a Product",
                life: 3000,
            });
        }
    };

    // Data Update
    const UpdateData = (data) => {
        if (data.list.length != 0) {
            axios
                .put(route("customer-opening.update", id), data)
                .then((response) => {
                    toast.current.show({
                        severity: "info",
                        summary: "Confirmed",
                        detail: response.data.success,
                        life: 3000,
                    });
                    setCustoemrList(response.data.customers);
                    setVisible(false);

                    reset({
                        warehouse_id: watch("warehouse_id"),
                        customer_id: "",
                        list: [],
                    });
                })
                .catch((error) => {
                    let errors = error.response.data.errors;
                    Object.keys(errors).forEach((field) => {
                        setError(field, {
                            type: "manual",
                            message: errors[field][0],
                        });
                    });
                });
        } else {
            toast.current.show({
                severity: "warn",
                summary: "Rejected",
                detail: "Must need a Product",
                life: 3000,
            });
        }
    };

    const customerTempelateIOptionList = (option) => {
        return (
            <div className="country-item">
                <div>
                    {option.name} ({option.code}) ({option.user_type})
                </div>
            </div>
        );
    };

    const filterCustomer = (event) => {
        setTimeout(() => {
            axios
                .post(route("customer-search"), { data: event.query })
                .then((response) => {
                    setCustomer(response.data.customer);
                });
        }, 250);
    };

    const selectedItem = (item) => {
        setSearchValue((old) => {
            return {
                ...old,
                company: "",
            };
        });
        let inputValue = "";

        if (item.name) {
            inputValue += item.name + " ";

            if (item.number) inputValue += "(" + item.number + ")";
        }

        const list = watch("list") || [];
        const index = list.length;

        if (index >= 1) {
            toast.current.show({
                severity: "warn",
                summary: "Rejected",
                detail: "Your company is already added.",
                life: 3000,
            });
        } else {
            setValue("customer_id", watch("customer_id"));

            if (
                Number(auth.user.supplier_id) === Number(item.id) ||
                auth.user.supplier_id == null
            ) {
                append({
                    opening_balance: "",
                    opening_date: "",
                    index: index,
                });
            }
        }
    };

    const handelDelete = (id) => {
        if (confirm("Are you sure you want to delete this record?")) {
            axios
                .delete(route("customer-opening.destroy", id))
                .then((response) => {
                    toast.current.show({
                        severity: "info",
                        summary: "Confirmed",
                        detail: response.data.success,
                        life: 3000,
                    });
                    setCustoemrList(response.data.customers);
                })
                .catch((error) => {
                    toast.current.show({
                        severity: "error",
                        summary: "Error",
                        detail: "Failed to delete record",
                        life: 3000,
                    });
                });
        }
    };

    return (
        <AuthenticatedLayout
            user={auth.user}
            header={
                <>
                    <h2 className="text-skin-header font-medium ">
                        Opening Balance
                    </h2>{" "}
                    <p className="text-skin-sub-header font-semibold text-xs">
                        {" "}
                        Home - Opening Balance
                    </p>
                </>
            }
            headerButton={<></>}
        >
            <Toast ref={toast} />
            <ConfirmPopup /> {/* View Table*/}
            <div className="card">
                <DataTable
                    className="defulattable"
                    value={customerList}
                    paginator
                    showGridlines
                    rows={10}
                    dataKey="id"
                    header={TableHeader}
                    filters={filters2}
                    emptyMessage="No product found."
                >
                    <Column
                        filterField="client.name"
                        body={(data) => {
                            return (
                                data.client.name +
                                " (" +
                                data.client.code +
                                ")" +
                                " (" +
                                data.client.number +
                                ")" +
                                " (" +
                                data.client.user_type +
                                ")"
                            );
                        }}
                        header="Custoemr/Retalier"
                    />
                    <Column
                        body={(data) => {
                            return new Date(
                                data.details[0].opening_date
                            ).toLocaleDateString("en-us");
                        }}
                        header="Opening Date"
                    />

                    <Column field="location.name" header="Warehouse/Shop" />

                    <Column
                        header="Action"
                        body={(rowData) => (
                            <>
                                {" "}
                                <ConfirmPopup />{" "}
                                {permission.includes(
                                    "customer_retailer_opening_edit"
                                ) && (
                                    <Button
                                        icon="pi pi-pencil"
                                        onClick={() => {
                                            setId(rowData.id);
                                            setVisible(true);
                                            setStatus("update");
                                            setValue(
                                                "customer_id",
                                                watch("customer_id")
                                            );
                                            setSearchValue((old) => {
                                                return {
                                                    ...old,
                                                    customer: rowData.client
                                                        ? rowData.client.name +
                                                          " (" +
                                                          rowData.client.code +
                                                          ")"
                                                        : "",
                                                };
                                            });

                                            reset({
                                                customer_id: rowData.client_id,
                                                warehouse_id:
                                                    rowData.warehouse_id,
                                                list: rowData.details
                                                    .filter(
                                                        (item) =>
                                                            Number(
                                                                auth.user
                                                                    .supplier_id
                                                            ) ===
                                                                Number(
                                                                    item.supplier_id
                                                                ) ||
                                                            auth.user
                                                                .supplier_id ===
                                                                null
                                                    )
                                                    .map((item, index) => ({
                                                        supplier_id: Number(
                                                            item.supplier_id
                                                        ),
                                                        supplier_info:
                                                            item.supplier_info,
                                                        opening_balance:
                                                            item.opening_balance,
                                                        opening_date: new Date(
                                                            item.opening_date
                                                        ),
                                                        index: index,
                                                    })),
                                            });
                                        }}
                                        className="p-button-rounded p-button-success mr-2 px-3 py-2  w-10 h-10 font-medium"
                                    />
                                )}
                                {permission.includes(
                                    "customer_retailer_opening_delete"
                                ) && (
                                    <Button
                                        icon="pi pi-trash"
                                        data-id={rowData.id}
                                        onClick={() => {
                                            handelDelete(rowData.id);
                                        }}
                                        className="p-button-rounded p-button-warning px-3 py-2  w-10 h-10  font-medium"
                                    />
                                )}
                            </>
                        )}
                        dataType="boolean"
                        bodyClassName="text-center"
                        style={{ minWidth: "8rem" }}
                    />
                </DataTable>
            </div>
            {/* View Table End*/}
            <Dialog
                header={() =>
                    status == "create"
                        ? "Opening Balance"
                        : "Update Opening Balance"
                }
                visible={visible}
                className=" w-[100%] min-h-[100%] md:w-[70vw] md:min-h-[50vh]"
                onHide={() => {
                    setVisible(false);

                    reset({
                        shop_id: "",
                        warehouse_id: watch("warehouse_id"),
                        list: [],
                    });
                }}
                footer={footerContent}
            >
                <form
                    onSubmit={
                        status == "create"
                            ? handleSubmit(StoreData)
                            : handleSubmit(UpdateData)
                    }
                    ref={formSubmit}
                >
                    <div className=" grid grid-cols-12 mt-6 gap-5">
                        <div className="p-float-label  col-span-12 md:col-span-6">
                            <Controller
                                name="customer_id"
                                control={control}
                                rules={{
                                    required:
                                        "Cutomer/Retalier field is required ",
                                }}
                                render={({ field, fieldState }) => (
                                    <span className="p-float-label">
                                        <AutoComplete
                                            value={search.customer}
                                            suggestions={customer}
                                            completeMethod={filterCustomer}
                                            aria-label="customer_id"
                                            dropdown
                                            itemTemplate={
                                                customerTempelateIOptionList
                                            }
                                            onChange={(e) => {
                                                if (e.value.name) {
                                                    setValue(
                                                        "customer_id",
                                                        e.value.id
                                                    );
                                                } else {
                                                    setValue(
                                                        "customer_id",
                                                        null
                                                    );
                                                }

                                                setSearchValue((old) => {
                                                    return {
                                                        ...old,
                                                        customer: e.value.name
                                                            ? e.value.name +
                                                              " (" +
                                                              e.value.code +
                                                              ")"
                                                            : e.value,
                                                    };
                                                });

                                                selectedItem(e.value);
                                            }}
                                            dropdownAriaLabel="Select Coustomer"
                                            className="w-full h-11"
                                        />

                                        <label htmlFor={field.name}>
                                            Search Customer & Retailer
                                        </label>
                                    </span>
                                )}
                            />
                            {getFormErrorMessageSingel("customer_id")}
                        </div>

                        {permission.includes(
                            "customer_retailer_superAdmin_access"
                        ) && (
                            <div className="p-float-label   col-span-12 md:col-span-6">
                                <Controller
                                    name="warehouse_id"
                                    control={control}
                                    rules={{
                                        required:
                                            "Warehouse/Shop field is required ",
                                    }}
                                    render={({ field, fieldState }) => (
                                        <span className="p-float-label">
                                            <WarehouseDropdown
                                                setPermission="customer_retailer_superAdmin_access"
                                                warehouse={field.value}
                                                setWarehouse={(data) => {
                                                    field.onChange(data);
                                                }}
                                            />
                                            <label htmlFor={field.name}>
                                                Select Warehouse/Shop
                                            </label>
                                        </span>
                                    )}
                                />

                                {getFormErrorMessageSingel("warehouse_id")}
                            </div>
                        )}
                    </div>

                    <DataTable
                        className="defulattable w-full overflow-x-auto"
                        value={fields}
                        showGridlines
                        dataKey="id"
                        header={CompanyTableHeader}
                        filters={filters}
                        emptyMessage="No Company found."
                    >
                        {/* <Column field="supplier_info" header="Company Name" /> */}
                        <Column
                            field="opening_balance"
                            header="Opening Balance"
                            body={(data, index) => {
                                return (
                                    <>
                                        <Controller
                                            control={control}
                                            name={`list.${data.index}.opening_balance`}
                                            rules={{
                                                required:
                                                    "Balance Field is required",
                                                min: {
                                                    value: 0,
                                                    message:
                                                        "nagative value not allow",
                                                },
                                            }}
                                            render={({ field }) => (
                                                <InputText
                                                    id={`opening_balance-${data.id}`}
                                                    className={`w-[7rem] md:w-full h-10 ${
                                                        errors?.list?.[data.id]
                                                            ?.opening_balance &&
                                                        "p-invalid"
                                                    }`}
                                                    value={watch(
                                                        `list.${data.index}.opening_balance`
                                                    )}
                                                    placeholder="Opening Balance"
                                                    onChange={(e) => {
                                                        setValue(
                                                            `list.${data.index}.opening_balance`,
                                                            e.target.value
                                                        );
                                                    }}
                                                    type="number"
                                                    min={0}
                                                />
                                            )}
                                        />
                                        {getFormErrorMessageMultiple(
                                            `opening_balance`,
                                            data.id
                                        )}
                                    </>
                                );
                            }}
                        />
                        <Column
                            field="opening_date"
                            header="Opening Date"
                            body={(data, index) => {
                                return (
                                    <>
                                        <Controller
                                            control={control}
                                            name={`list.${index.rowIndex}.opening_date`}
                                            rules={{
                                                required:
                                                    "Date Field is required",
                                            }}
                                            render={({
                                                field: { onChange, value },
                                            }) => (
                                                <Calendar
                                                    id={`opening_date-${index.rowIndex}`}
                                                    className={`w-[7rem] md:w-full h-10 ${
                                                        errors?.list?.[
                                                            index.rowIndex
                                                        ]?.opening_date &&
                                                        "p-invalid"
                                                    }`}
                                                    value={watch(
                                                        `list.${index.rowIndex}.opening_date`
                                                    )}
                                                    placeholder="Opening Date"
                                                    onChange={(e) => {
                                                        const utcDate =
                                                            new Date(
                                                                Date.UTC(
                                                                    e.value.getFullYear(),
                                                                    e.value.getMonth(),
                                                                    e.value.getDate(),
                                                                    0,
                                                                    0,
                                                                    0
                                                                )
                                                            );
                                                        setValue(
                                                            `list.${index.rowIndex}.opening_date`,
                                                            new Date(utcDate)
                                                        );
                                                    }}
                                                />
                                            )}
                                        />
                                        {getFormErrorMessageMultiple(
                                            `opening_date`,
                                            index.rowIndex
                                        )}
                                    </>
                                );
                            }}
                        />
                        {status == "create" && (
                            <Column
                                field="Action"
                                header="Action"
                                body={(data, index) => {
                                    return (
                                        <Button
                                            icon="pi pi-trash"
                                            onClick={(e) => {
                                                e.preventDefault();

                                                confirmPopup({
                                                    target: e.currentTarget,
                                                    message:
                                                        "Do you want to delete this record?",
                                                    icon: "pi pi-info-circle",
                                                    acceptClassName:
                                                        "p-button-danger",
                                                    accept() {
                                                        let lists =
                                                            watch("list");
                                                        let remove =
                                                            lists.filter(
                                                                (item) =>
                                                                    item.supplier_id !=
                                                                    data.supplier_id
                                                            );
                                                        reset({
                                                            customer_id:
                                                                watch(
                                                                    "customer_id"
                                                                ),
                                                            warehouse_id:
                                                                watch(
                                                                    "warehouse_id"
                                                                ),
                                                            list: remove.map(
                                                                (e) => {
                                                                    return {
                                                                        supplier_id:
                                                                            e[
                                                                                "supplier_id"
                                                                            ],
                                                                        supplier_info:
                                                                            e[
                                                                                "supplier_info"
                                                                            ],
                                                                        opening_balance:
                                                                            e[
                                                                                "opening_balance"
                                                                            ],
                                                                        opening_date:
                                                                            e[
                                                                                "opening_date"
                                                                            ],
                                                                        opening_date:
                                                                            e[
                                                                                "opening_date"
                                                                            ],
                                                                    };
                                                                }
                                                            ),
                                                        });
                                                    },
                                                    reject() {
                                                        toast.current.show({
                                                            severity: "warn",
                                                            summary: "Rejected",
                                                            detail: "You have rejected",
                                                            life: 3000,
                                                        });
                                                    },
                                                });
                                            }}
                                            className="p-button-rounded p-button-warning px-3 py-2  w-10 h-10  font-medium"
                                        />
                                    );
                                }}
                            />
                        )}
                    </DataTable>
                </form>
            </Dialog>
        </AuthenticatedLayout>
    );
}

export default OpeningBalance;
