import React, { useContext, useEffect, useRef, useState } from "react";
import AuthenticatedLayout from "@/Layouts/AuthenticatedLayout";
import { InputText } from "primereact/inputtext";
import { Button } from "primereact/button";
import { Dialog } from "primereact/dialog";
import { useForm } from "react-hook-form";
import axios from "axios";
import { Toast } from "primereact/toast";
import { authUser } from "@/Components/AuthProvider";
import { can } from "@/Utils/helper";
import DataTable from "@/Components/DataTable";
import FormFieldRenderer from "@/Components/FormFieldRenderer";

export default function Unit({ auth }) {
  const { permission } = useContext(authUser);
  const [status, setStatus] = useState("create");
  const [visible, setVisible] = useState(false);
  const [parent, setParent] = useState([]);
  const [serialMap, setSerialMap] = useState({});
  const [refreshTrigger, setRefreshTrigger] = useState(0);
  const [updateId, setUpdateId] = useState(null);
  const [serverErrors, setServerErrors] = useState(false);

  const defaultValues = {
    name: "",
    parent_id: "",
    short_name: "",
    base_unit: "",
    converted_ratio: "",
    tolerance: "",
  };
  const toast = useRef(null);
  const formSubmit = useRef(null);
  const {
    control,
    formState: { errors: rhfErrors },
    handleSubmit,
    reset,
    setError,
    watch,
  } = useForm({ defaultValues });

  const formdata = watch();

  useEffect(() => {
    axios.get("/uniteview").then((res) => {
      setParent(res.data.parent || []);
    });
  }, []);
  const resetForm = () => {
    setServerErrors(false);
    setVisible(false);
    setUpdateId(null);
    reset(defaultValues);
  };

  const buildSerialMap = (items = []) => {
    const nextSerialMap = {};
    const parentNoById = {};
    const childCounterByParentId = {};
    let parentNo = 0;

    for (const row of items) {
      const isChild = !!row?.parent_id;

      if (!isChild) {
        parentNo += 1;
        parentNoById[row.id] = parentNo;
        childCounterByParentId[row.id] = 0;
        nextSerialMap[row.id] = String(parentNo);
        continue;
      }

      const pid = row.parent_id;
      if (!parentNoById[pid]) {
        parentNo += 1;
        parentNoById[pid] = parentNo;
        childCounterByParentId[pid] = 0;
      }

      childCounterByParentId[pid] = (childCounterByParentId[pid] || 0) + 1;
      nextSerialMap[row.id] = `${parentNoById[pid]}.${childCounterByParentId[pid]}`;
    }

    return nextSerialMap;
  };

  const handleTableDataChange = (items = []) => {
    setSerialMap(buildSerialMap(items));
  };

  const StoreData = (data) => {
    axios
      .post(route("unit.store"), data)
      .then((response) => {
        toast.current?.show?.({
          severity: "success",
          summary: response.data.success,
          detail: "Data Inserted",
          life: 3000,
          className: "custom-toast-class",
        });
        setVisible(false);
        setServerErrors(false);
        reset(defaultValues);
        setParent(response.data.parent || parent);
        setRefreshTrigger((prev) => prev + 1);
      })
      .catch((error) => {
        const errors = error?.response?.data?.errors;
        setServerErrors(errors || false);
        if (errors) {
          Object.keys(errors).forEach((field) => {
            setError(field, { type: "manual", message: errors[field][0] });
          });
        }
        toast.current?.show?.({
          severity: "error",
          summary: "Error",
          detail:
            error?.response?.data?.error ||
            error?.response?.data?.message ||
            "Failed to create unit.",
          life: 4000,
        });
      });
  };

  const UpdateData = (data) => {
    axios
      .put(route("unit.update", updateId), data)
      .then((response) => {
        toast.current?.show?.({
          severity: "success",
          summary: response.data.success,
          detail: "Data Updated",
          life: 3000,
          className: "custom-toast-class",
        });
        setVisible(false);
        setServerErrors(false);
        reset(defaultValues);
        setParent(response.data.parent || parent);
        setRefreshTrigger((prev) => prev + 1);
      })
      .catch((error) => {
        const errors = error?.response?.data?.errors;
        setServerErrors(errors || false);
        if (errors) {
          Object.keys(errors).forEach((field) => {
            setError(field, { type: "manual", message: errors[field][0] });
          });
        }
        toast.current?.show?.({
          severity: "error",
          summary: "Error",
          detail:
            error?.response?.data?.error ||
            error?.response?.data?.message ||
            "Failed to update unit.",
          life: 4000,
        });
      });
  };

  const handaleEdit = (row) => {
    setVisible(true);
    setStatus("update");
    setUpdateId(row.id);
    setServerErrors(false);
    reset({
      name: row.name ?? "",
      parent_id: row.parent_id ?? "",
      short_name: row.short_name ?? "",
      base_unit: row.base_unit ?? "",
      converted_ratio: row.converted_ratio ?? "",
      tolerance: row.tolerance ?? "",
    });
  };

  const handaleDelete = (id) => {
    if (confirm("Do you want to delete this record?")) {
      axios
        .delete(route("unit.destroy", id))
        .then((response) => {
          toast.current?.show?.({
            severity: "success",
            summary: "Success",
            detail: response.data.success,
            life: 3000,
          });
          setParent(response.data.parent || parent);
          setRefreshTrigger((prev) => prev + 1);
        })
        .catch((error) => {
          toast.current?.show?.({
            severity: "error",
            summary: "Error",
            detail: error?.response?.data?.error || "Failed to delete unit",
            life: 4000,
          });
        });
    }
  };

  const renderHeader = ({ search, setSearch }) => {
    return (
      <>
        {permission.includes("unit_create") && (
          <Button
            type="button"
            icon={<span className="pi pi-plus text-sm pr-1" />}
            label="Add"
            onClick={() => {
              setVisible(true);
              setStatus("create");
              setUpdateId(null);
              setServerErrors(false);
              reset(defaultValues);
            }}
            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={search}
            onChange={(e) => setSearch(e.target.value)}
            placeholder="Search"
          />
        </span>
      </>
    );
  };

  const footerContent = (
    <div className="flex justify-end">
      <Button
        label="Cancel"
        icon="pi pi-times"
        onClick={() => {
          setVisible(false);
          resetForm();
        }}
        className="p-button-text w-13 text-sm"
      />
      <Button
        label="Save"
        type="submit"
        icon="pi pi-check"
        onClick={() => {
          formSubmit.current.dispatchEvent(
            new Event("submit", { bubbles: true })
          );
        }}
        className="p-button-text w-13 text-sm"
      />
    </div>
  );

  return (
    <AuthenticatedLayout
      user={auth.user}
      header={
        <>
          <h2 className="text-skin-header font-medium ">Unit</h2>{" "}
          <p className="text-skin-sub-header font-semibold text-xs">
            {" "}
            Home - Unit
          </p>
        </>
      }
      headerButton={<></>}
    >
      <Toast ref={toast} />
      <DataTable
        key={refreshTrigger}
        fetchUrl={"/uniteview"}
        emptyMessage="No unit found."
        headerActions={renderHeader}
        className="data-table"
        onDataChange={handleTableDataChange}
        columns={[
          {
            field: "serial",
            header: "SL",
            style: { width: "70px" },
            headerStyle: { textAlign: "center" },
            body: (rowData) => serialMap?.[rowData?.id] || "",
          },
          {
            field: "name",
            header: "Unit",
            style: { minWidth: "12rem" },
            headerStyle: { textAlign: "center" },
            body: (rowData) => (
              <div
                style={{
                  paddingLeft: rowData.parent_id ? "2rem" : "0",
                  fontWeight: rowData.parent_id ? "normal" : "600",
                }}
              >
                {rowData.parent_id && (
                  <span style={{ marginRight: "0.5rem", color: "#6b7280" }}>└─</span>
                )}
                {rowData.name}
              </div>
            ),
          },
          {
            field: "short_name",
            header: "Short name",
            style: { minWidth: "12rem" },
            headerStyle: { textAlign: "center" },
            body: (rowData) => rowData.short_name ?? "N/A",
          },
          ((can("for_labware", 'hide') || can('for_restaurant', 'hide'))
            ? [
              {
                field: "base_unit",
                header: "Base Unit",
                style: { minWidth: "12rem" },
                headerStyle: { textAlign: "center" },
                body: (rowData) => rowData.base_unit ?? "N/A",
              },
              {
                field: "converted_ratio",
                header: "Converted ratio",
                style: { minWidth: "12rem" },
                headerStyle: { textAlign: "center" },
                body: (rowData) => rowData.converted_ratio ?? "N/A",
              },
            ]
            : []),
          {
            type: "action",
            header: "Action",
            style: { width: "100px" },
            permission,
            context: {
              onEdit: (data) => handaleEdit(data),
              onDelete: (id) => handaleDelete(id),
            },
            actions: [
              {
                label: "Edit",
                icon: "pi pi-pencil",
                permission: "unit_edit",
                handler: (rowData, ctx) => ctx.onEdit(rowData),
              },
              {
                label: "Delete",
                icon: "pi pi-trash",
                permission: "unit_delete",
                handler: (rowData, ctx) => ctx.onDelete(rowData.id),
              },
            ],
          },
        ]}
      />

      {/* Create Model*/}
      <Dialog
        header={() => (status == "create" ? "Create Unit" : "Update Unit")}
        visible={visible}
        style={{ width: "450px" }}
        onHide={() => {
          setVisible(false);
          resetForm();
        }}
        footer={footerContent}
      >
        <form
          onSubmit={handleSubmit(status == "create" ? StoreData : UpdateData)}
          ref={formSubmit}
        >
          {/*
            Merge client-side (react-hook-form) errors with server-side errors
            so FormFieldRenderer can display messages consistently.
          */}
          <div className="grid grid-cols-12  gap-y-6 pt-6 ">
            {(() => {
              const mergedErrors = {
                ...(serverErrors || {}),
                ...(rhfErrors || {}),
              };
              return (
                <FormFieldRenderer
                  formName="unit"
                  formData={formdata}
                  setFormData={() => { }}
                  errors={mergedErrors}
                  context={{
                    control,
                    parent,
                  }}
                />
              );
            })()}
          </div>
        </form>
      </Dialog>
      {/* Create Model End*/}
    </AuthenticatedLayout>
  );
}
