/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/no-unused-vars */
import React, {
  useRef,
  useState,
  useMemo,
  forwardRef,
  useImperativeHandle,
  useEffect,
} from "react";
import {
  Formik,
  Field,
  Form,
  ErrorMessage,
  FormikHelpers,
  FormikProps,
} from "formik";
import * as Yup from "yup";
import { Row } from "react-bootstrap";
import HourGlassLoader from "../../../Loader/Loader";
import SelectField from "./SelectField";
import InputFieldCustom from "./InputFieldCustom";
import ShipmentTypeSelector from "./ShipmentTypeSelector";
import ShipmentPreview from "./ShipmentPreview";
import { toast } from "react-toastify";
import { createShipment, getWarehouse, updateShipment } from "../../../../Api/ShipmentApi";
import { modeOfTransportOptions } from "@/Constant/options";
import ModeOfTransportTypeSelector from "./ModeOfTransportTypeSelector";
  import { ShipmentStatus } from "@/Constant/enums";
  import { useRouter } from "next/navigation";  // not "next/router"
import { DefaultShipmentType } from "@/Constant";
  // Local option type compatible with SelectField
type SelectOptionType = { id: string | number; label: string };

interface ServiceType {
  id: number;
  name: string;
}

export interface Option {
  id: string;
  label: string;
}

export interface ShipmentFormRef {
  submitForm: () => void;
}

export interface ShipmentDetailsFormProps {
  onClose?: () => void;
  editShipment?: any;
  step: number;
  onStepChange?: (step: number) => void;
  setShipmentDetails: any;
}

export interface ShipmentFormValuesTypes {
  [key: string]: any;
}

// Mock service icon map until import path is resolved
const serviceIconMapShipment: Record<string, { icon: string; color: string }> = {
  Import: { icon: "arrow-down", color: "color-yellow2" },
  Export: { icon: "arrow-up", color: "color-yellow2" },
};
  const initialValues: any = {
  shipped_by: "",
  received_by: "",
  // upload_manifest: null,
  shipment_number: "",
  vessel_name: "",
  shipment_date: "",
  eta_date: "",
  shipment_address: "",
  receiver_address: "",
  mode_of_transport: "",
  cargo_type: "",
  remarks: "",
    status: ShipmentStatus.Created,
    service_type: "",
};
  // Validation Schema using Yup
  const validationSchema = Yup.object().shape({
    status: Yup.mixed<number | string>()
      .oneOf([ShipmentStatus.Created, ShipmentStatus.Shipped])
      .required("Status is required"),
    service_type: Yup.mixed<number | string>()
      .required("Service type is required"),

    // Always required in both statuses
    shipped_by: Yup.string().required("Shipped by is required"),
    received_by: Yup.string().required("Received by is required"),

    shipment_address: Yup.string()
      .max(255, "Max 255 characters allowed")
      .required("Shipment address is required"),

    receiver_address: Yup.string()
      .max(255, "Max 255 characters allowed")
      .required("Receiver address is required"),

    // Required only when status is Shipped
    shipment_number: Yup.string().when("status", (status, schema) =>
      Number(status) === ShipmentStatus.Shipped
        ? schema.required("Shipment number is required")
        : schema
    ),
    mode_of_transport: Yup.mixed<string | number>().when("status", (status, schema) =>
      Number(status) === ShipmentStatus.Shipped
        ? schema.required("Mode of transport is required")
        : schema
    ),
    cargo_type: Yup.string().when("status", (status, schema) =>
      Number(status) === ShipmentStatus.Shipped
        ? schema.required("Cargo type is required")
        : schema
    ),
    vessel_name: Yup.string().when("status", (status, schema) =>
      Number(status) === ShipmentStatus.Shipped
        ? schema.required("Vessel name is required")
        : schema
    ),
    shipment_date: Yup.string().when("status", (status, schema) =>
      Number(status) === ShipmentStatus.Shipped
        ? schema.required("Shipment date is required")
        : schema
    ),
    eta_date: Yup.string().when("status", (status, schema) =>
      Number(status) === ShipmentStatus.Shipped
        ? schema.required("ETA date is required")
        : schema
    ),

    // Remarks never mandatory
    remarks: Yup.string().max(255, "Max 255 characters allowed"),
  });


const ShipmentDetails = forwardRef<ShipmentFormRef, ShipmentDetailsFormProps>(
  ({ onClose, editShipment, step, onStepChange, setShipmentDetails }, ref) => {
    const [isLoading, setIsLoading] = useState(false);
    const router = useRouter();
    const serviceTypes: ServiceType[] = [
      { id: 1, name: "Import" },
      { id: 2, name: "Export" },
    ];

    const yesNoOptions: Option[] = [
      { id: "yes", label: "Yes" },
      { id: "no", label: "No" },
    ];
    const mapEditShipmentToFormValues = (shipment: any) => {
      if (!shipment) return initialValues;
      
      // Resolve service type from available shipment data
      const matchedServiceTypeLocal =
        serviceTypes.find((type) => type.name === shipment.type?.name) || null;

      return {
        shipped_by: shipment.shippedByCustomerId?.toString() ?? shipment.shippedByWarehouseId?.toString() ?? "",
        received_by: shipment.receivedByCustomerId?.toString() ?? shipment.receivedByWarehouseId?.toString() ?? "",
        shipment_number: shipment.shipmentNumber || "",
        vessel_name: shipment.vesselName || "",
        shipment_date: shipment.shipmentDate || "",
        eta_date: shipment.etaDate || "",
        shipment_address: shipment.shippedByAddress || "",
        receiver_address: shipment.receivedByAddress || "",
        mode_of_transport: shipment?.mode?.id || "",
        cargo_type: shipment.cargoName || "",
        remarks: shipment.remarks || "",
        status: shipment.status?.id ?? shipment.status ?? ShipmentStatus.Created,
        service_type: matchedServiceTypeLocal?.id ?? shipment.type?.id ?? "",
      };
    };
    const [selectedServiceType, setSelectedServiceType] =
      useState<ServiceType | null | any>(null);
    const formikRef = useRef<FormikProps<ShipmentFormValuesTypes>>(null);

    // Get current user data from localStorage
    const [currentUserData, setCurrentUserData] = useState<any>(null);
    useImperativeHandle(ref, () => ({
      submitForm: () => {
        formikRef.current?.submitForm();
      },
    }));

    // Load current user data from localStorage on component mount
    React.useEffect(() => {
      try {
        const storedUser = localStorage.getItem("ALL_DATA");
        const allData = storedUser ? JSON.parse(storedUser)?.data : null;
        setCurrentUserData(allData);
      } catch (error) {
        console.error("Error parsing localStorage data:", error);
      }
    }, []);
    const formInitialValues = useMemo(() => {
      if (editShipment?.id) {
        const mappedValues = mapEditShipmentToFormValues(editShipment);
        // Set selected service type for UI
        const matchedServiceType =
          serviceTypes.find((type) => type.name === editShipment.type?.name) || null;
        setSelectedServiceType(matchedServiceType);
        return mappedValues;
      }
      // For new shipment: use default type
      setSelectedServiceType(DefaultShipmentType);
      return {
        ...initialValues,
        service_type: DefaultShipmentType.id,
      };
    // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [editShipment]);
    useEffect(() => {
      if (!editShipment?.id && formikRef.current) {
        formikRef.current.setFieldValue("service_type", DefaultShipmentType.id);
        handleChange(DefaultShipmentType.name); // apply default auto-fill logic
      }
    // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [editShipment]);
    // Run default service type logic after form is initialized
useEffect(() => {
  if (!editShipment?.id && formikRef.current && currentUserData?.id) {
    // Set service type in form
    formikRef.current.setFieldValue("service_type", DefaultShipmentType.id);

    // Apply default auto-fill logic (calls handleChange)
    handleChange(DefaultShipmentType.name);
  }
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [editShipment, currentUserData]);

    // const formInitialValues = useMemo(() => {
    //   return editShipment?.id
    //     ? { ...initialValues, ...editShipment }
    //     : initialValues;
    // }, [editShipment]);

    const handleChange = (serviceName: string | null) => {
      const matched =
        serviceTypes.find((type) => type.name === serviceName) || null;
      setSelectedServiceType(matched);
      
      // Reset and auto-fill shipped_by and received_by when service type changes
      if (formikRef.current && currentUserData?.id) {
        // Keep a hidden field in sync for validation
        formikRef.current.setFieldValue("service_type", matched?.id ?? "");
        if (matched?.name === "Import") {
          // For Import: received_by = current user, shipped_by = empty (user selects)
          formikRef.current.setFieldValue("received_by", currentUserData.id.toString());
          formikRef.current.setFieldValue("shipped_by", "");
        } else if (matched?.name === "Export") {
          // For Export: shipped_by = current user, received_by = empty (user selects)
          formikRef.current.setFieldValue("shipped_by", currentUserData.id.toString());
          formikRef.current.setFieldValue("received_by", "");
        } else {
          // Reset both fields
          formikRef.current.setFieldValue("shipped_by", "");
          formikRef.current.setFieldValue("received_by", "");
        }
      }
    };

    const [shippedByOptions, setShippedByOptions] = useState<SelectOptionType[]>([]);

    useEffect(() => {
      const fetchOptions = async () => {
        if (!selectedServiceType) {
          setShippedByOptions([]);
          return;
        }
  
        if (selectedServiceType.name === "Import") {
          // Fetch from API instead of static options
          try {
            const warehouseData = await getWarehouse();
            // Map warehouse data into your OptionType shape, adjust keys as needed
            const options = warehouseData.map((item: any) => ({
              id: item.id.toString(),
              label: item.name || item.company_name || `Warehouse ${item.id}`,
            }));
            setShippedByOptions(options);
          } catch (error) {
            console.error("Error fetching warehouse data:", error);
            setShippedByOptions([]);
          }
        } else if (selectedServiceType.name === "Export") {
          // Fetch from API instead of static options
          try {
            const warehouseData = await getWarehouse();
            // Map warehouse data into your OptionType shape, adjust keys as needed
            const options = warehouseData.map((item: any) => ({
              id: item.id.toString(),
              label: item.name || item.company_name || `Warehouse ${item.id}`,
            }));
            setShippedByOptions(options);
          } catch (error) {
            console.error("Error fetching warehouse data:", error);
            setShippedByOptions([]);
          }
        } else {
          setShippedByOptions([]);
        }
      };
      fetchOptions();
    }, [selectedServiceType, currentUserData, editShipment]);
  
    const remainingChars = (value: string) => 255 - (value?.length || 0);

    const handleSubmit = async (values: any, actions: FormikHelpers<any>) => {
      if (step === 1) {
        // Validate form and create shipment
        try {
          setIsLoading(true);
          
          // Extract shipped_by and received_by IDs from form values
          const shippedById = values.shipped_by; // assuming it's already the id string/number
          const receivedById = values.received_by;

          // Prepare shipment data with correct keys
          const shipmentData = {
            ...values,
            type: selectedServiceType?.id ?? values?.service_type ?? null,
            shipped_by_id: shippedById,
            received_by_id: receivedById,
            cargo_name: values?.cargo_type,
            shipped_by_address: values?.shipment_address,
            received_by_address: values?.receiver_address,
            mode: values?.mode_of_transport,
            status: Number(values?.status),
          };

          // Remove original keys if you want (optional)
          delete shipmentData.shipped_by;
          delete shipmentData.received_by;
          delete shipmentData.service_type;
          delete shipmentData?.cargo_type
          delete shipmentData?.shipment_address
          delete shipmentData?.receiver_address
          delete shipmentData?.mode_of_transport


          const response = editShipment?.id ? await updateShipment({...shipmentData, shipment_id: editShipment?.id}): await createShipment(shipmentData);
          if (response?.status) {
            // onClose?.();
            // setShipmentDetails(response?.data)
            router.push(`${window.location.pathname}?id=${response?.data?.id}`);
            if(shipmentData?.status === ShipmentStatus.Shipped)
              window.location.href = `${window.location.pathname}?id=${response?.data?.id}`
            toast.success(response?.message, {
              position: "top-right",
              autoClose: 3000,
            });
            
            // Move to step 2
            if (onStepChange) {
              onStepChange(2);
            }
          } else {
            toast.error(response?.message || "Failed to create shipment", {
              position: "top-right",
              autoClose: 3000,
            });
          }
        } catch (error: any) {
          console.error("Error creating shipment:", error);
          toast.error("An error occurred while creating the shipment", {
            position: "top-right",
            autoClose: 3000,
          });
        } finally {
          setIsLoading(false);
          actions.setSubmitting(false);
        }
      } else if (step === 2) {
        // onClose?.();
      }
    };
    // const isFormValid = (
    //   values: any,
    //   fieldName?: string
    // ): { valid: boolean; field?: string } => {
    //   const requiredFields: Record<string, boolean> = {
    //     shipped_by: !!values.shipped_by,
    //     received_by: !!values.received_by,
    //     shipment_address: !!values.shipment_address,
    //     receiver_address: !!values.receiver_address,
    //   };
    
    //   if (Number(values.status) === ShipmentStatus.Shipped) {
    //     requiredFields.shipment_number = !!values.shipment_number;
    //     requiredFields.mode_of_transport = !!values.mode_of_transport;
    //     requiredFields.cargo_type = !!values.cargo_type;
    //     requiredFields.vessel_name = !!values.vessel_name;
    //     requiredFields.shipment_date = !!values.shipment_date;
    //     requiredFields.eta_date = !!values.eta_date;
    //   }
    
    //   if (fieldName) {
    //     return {
    //       valid: requiredFields[fieldName],
    //       field: fieldName,
    //     };
    //   }
    
    //   // Whole form check (first invalid field if any)
    //   for (const [field, isValid] of Object.entries(requiredFields)) {
    //     if (!isValid) return { valid: false, field };
    //   }
    
    //   return { valid: true };
    // };
    const isFieldRequired = (fieldName: string, values: any): boolean => {
      // Always required
      const alwaysRequired = ["shipped_by", "received_by", "shipment_address", "receiver_address"];
    
      if (alwaysRequired.includes(fieldName)) {
        return true;
      }
    
      // Required only when status = SHIPPED
      if (Number(values.status) === ShipmentStatus.Shipped) {
        const shippedRequired = [
          "shipment_number",
          "mode_of_transport",
          "cargo_type",
          "vessel_name",
          "shipment_date",
          "eta_date",
        ];
        return shippedRequired.includes(fieldName);
      }
    
      // Otherwise not required
      return false;
    };
    
    return (
      <>
      <style>
        {`
          .input-style.has-icon.has-borders i:first-child { top: 41%; }
          .react-select__input-container .react-select__input { height: 38px !important; }
          .react-select__control, .css-13cymwt-control { border-radius: 10px; }
        `}
      </style>
        <Formik
          innerRef={formikRef}
          enableReinitialize
          initialValues={formInitialValues}
          validationSchema={validationSchema}
          onSubmit={handleSubmit}
        >
          {({ values, errors, touched, setFieldValue }: any) => (
            <Form>
              <div className="content mb-0 mt-0">
                <Row className="g-3">
                  {step === 1 && (
                    <div className="scrollWrap step1-package">
                      <div className="row mx-0">
                        <div className="col-lg-3 shipment-service-type01 mb-4">
                          <h5 className="font-15 pb-1">Service Type</h5>
                          <ShipmentTypeSelector
                            serviceTypes={serviceTypes}
                            selectedServiceType={selectedServiceType}
                            onChange={handleChange}
                            errors={{ serviceType: "" }}
                            serviceIconMap={serviceIconMapShipment}
                            allowedServiceTypeId={null}
                            type="shipment"
                          />
                        </div>
                        <div className="col-lg-8 mb-4">
                          {/* <h5 className="font-15 pb-1">Mode of Transport</h5>
                          <ModeOfTransportTypeSelector
                            serviceTypes={serviceTypes}
                            selectedServiceType={selectedServiceType}
                            onChange={handleChange}
                            errors={{ serviceType: "" }}
                            serviceIconMap={serviceIconMapShipment}
                            allowedServiceTypeId={null}
                            type="shipment"
                          /> */}
                        </div>
                        {/* Conditional Shipped By field */}
                        {selectedServiceType?.name !== "Export" ? (
                          <SelectField
                            label="Shipped By"
                            name="shipped_by"
                            placeholder={
                              selectedServiceType?.name === "Export" 
                                ? "Current User (Auto-filled)" 
                                : "Select Shipped By"
                            }
                            options={shippedByOptions || []}
                            disabled={selectedServiceType?.name === "Export"}
                            required={isFieldRequired('shipped_by', values)}
                          />
                        ) : selectedServiceType?.name !== "Import" && (
                          <SelectField
                            label="Received By"
                            name="received_by"
                            placeholder={
                              selectedServiceType?.name === "Import" 
                                ? "Current User (Auto-filled)" 
                                : "Select Received By"
                            }
                            // options={getReceivedByOptions()}
                            options={shippedByOptions || []}
                            disabled={selectedServiceType?.name === "Import"}
                            required={isFieldRequired('shipped_by', values)}
                          />
                        )}

                        {/* Shipment Address */}
                        <div className="input-style input-style-always-active has-borders has-icon validate-field col-lg-3">
                          <div className="position-relative input-icon-position input-icon-select">
                            <i
                              className="ri ri-pencil-line color-primary"
                              style={{ top: 28 }}
                            />
                            <Field
                              as="textarea"
                              className={`form-control ${
                                touched.shipment_address &&
                                errors.shipment_address
                                  ? "is-invalid"
                                  : ""
                              }`}
                              name="shipment_address"
                              placeholder="Shipment address"
                              maxLength={255}
                            />
                          </div>
                          <label className="color-theme opacity-80 text-uppercase font-700 font-10">
                            Shipment address: <b className="color-red">*</b>
                          </label>
                          <div className="d-flex justify-content-between px-2">
                            {touched.shipment_address &&
                              errors.shipment_address && (
                                <div className="text-danger error-box">
                                  {errors.shipment_address}
                                </div>
                              )}
                            <div className="text-muted small">
                              {remainingChars(values.shipment_address)} characters
                              remaining
                            </div>
                          </div>
                        </div>

                        {/* Receiver Address */}
                        <div className="input-style input-style-always-active has-borders has-icon validate-field col-lg-3">
                          <div className="position-relative input-icon-position input-icon-select">
                            <i
                              className="ri ri-pencil-line color-primary"
                              style={{ top: 28 }}
                            />
                            <Field
                              as="textarea"
                              className={`form-control ${
                                touched.receiver_address &&
                                errors.receiver_address
                                  ? "is-invalid"
                                  : ""
                              }`}
                              name="receiver_address"
                              placeholder="Receiver address"
                              maxLength={255}
                            />
                          </div>
                          <label className="color-theme opacity-80 text-uppercase font-700 font-10">
                            Receiver address: <b className="color-red">*</b>
                          </label>
                          <div className="d-flex justify-content-between px-2">
                            {touched.receiver_address &&
                              errors.receiver_address && (
                                <div className="text-danger error-box">
                                  {errors.receiver_address}
                                </div>
                              )}
                            <div className="text-muted small">
                              {remainingChars(values.receiver_address)} characters
                              remaining
                            </div>
                          </div>
                        </div>
                        <InputFieldCustom
                          name="shipment_number"
                          type="text"
                          label="Shipment Number"
                          iconClass="ri-hashtag"
                          placeholder="Enter Shipment Number"
                          required={isFieldRequired('shipment_number', values)}
                        />
                        <SelectField
                          label="Mode Of Transport"
                          name="mode_of_transport"
                          placeholder="Select Mode Of Transport"
                          options={modeOfTransportOptions}
                          required={isFieldRequired('mode_of_transport', values)}
                        />
                                              <InputFieldCustom
                          name="cargo_type"
                          type="text"
                          label="Cargo Type"
                          iconClass="ri-hashtag"
                          placeholder="Enter Cargo Type"
                          required={isFieldRequired('cargo_type', values)}
                        />
                        <InputFieldCustom
                          name="vessel_name"
                          type="text"
                          label="Vessel Name"
                          iconClass="ri-hashtag"
                          placeholder="Enter Vessel Name"
                          required={isFieldRequired('vessel_name', values)}
                        />
                        <InputFieldCustom
                          name="shipment_date"
                          type="date"
                          label="Shipment Date"
                          iconClass="ri-calendar-line"
                          placeholder="Select Shipment Date"
                          required={isFieldRequired('shipment_date', values)}
                        />
                        <InputFieldCustom
                          name="eta_date"
                          type="date"
                          label="ETA Date"
                          iconClass="ri-calendar-check-line"
                          placeholder="Select ETA Date"
                          required={isFieldRequired('eta_date', values)}
                        />
                        <SelectField
                            label="Status"
                            name="status"
                            placeholder="Select Status"
                            options={[
                              { id: ShipmentStatus.Created, label: "Created" },
                              { id: ShipmentStatus.Shipped, label: "Shipped" },
                            ]}
                          />

                        <div className="input-style input-style-always-active has-borders has-icon validate-field col-lg-6">
                          <div className="position-relative input-icon-position input-icon-select">
                            <i
                              className="ri ri-pencil-line color-primary"
                              style={{ top: 28 }}
                            />
                            <Field
                              as="textarea"
                              className="form-control"
                              name="remarks"
                              placeholder="Type here..."
                              maxLength={255}
                            />
                          </div>
                          <label className="color-theme opacity-80 text-uppercase font-700 font-10">
                            Remarks if any
                          </label>
                          <div className="d-flex justify-content-between px-2">
                            <div className="text-muted small">
                              {remainingChars(values.remarks)} characters
                              remaining
                            </div>
                          </div>
                        </div>
                      </div>
                    </div>
                  )}

                  {step === 2 && (
                    <>
                      <ShipmentPreview editShipment={editShipment} setShipmentDetails={setShipmentDetails}/>
                    </>
                  )}
                </Row>
              </div>
            </Form>
          )}
        </Formik>

        {isLoading && <HourGlassLoader />}
      </>
    );
  }
);

ShipmentDetails.displayName = "ShipmentDetails";
export default ShipmentDetails;
