/* eslint-disable @next/next/no-img-element */
/* eslint-disable @typescript-eslint/no-explicit-any */
import React, { useState, useEffect } from "react";
import CreateOrderFooter from "./CreateOrderFooter";
import ServiceCard from "./Step2/ServiceCard";
import ServiceCardSkeleton from "./Step2/ServiceCardSkeleton";
import { useAppSelector } from "@/Redux/Hooks";
import {
  getAllShippingRates,
  initiateInternationalDraftOrder,
} from "../../../../Api/InternationalOrderApi";
import { useCurrency } from "@/context/CurrencyContext";

type Step2Props = {
  onSave: (data: any) => void;
  step: number;
  setStep: React.Dispatch<React.SetStateAction<number>>;
  defaultOrderDetails: any;
  isEditMode?: boolean;
};

const Step2: React.FC<Step2Props> = ({
  onSave,
  step,
  setStep,
  defaultOrderDetails,
  isEditMode,
}) => {
    const { currencyName } = useCurrency();

  const [isLoading, setIsLoading] = useState<boolean>(true);
  const [selectedServiceId, setSelectedServiceId] = useState<string | null>(
    null,
  );
  const [carriers, setCarriers] = useState<any[]>([]);
  const [countries, setCountries] = useState<any[]>([]);

  const createOrderData: any = useAppSelector((state) => state.createOrder);
  const step1Data = createOrderData?.step1;
  console.log(step1Data, "step1Data");

  // Fetch countries list to get country codes if needed
  useEffect(() => {
    const fetchCountries = async () => {
      try {
        const { getMasterList } = await import("../../../../Api/MastersApi");
        const response = await getMasterList("country");
        if (response?.status) {
          // normalize shape to match OptionType used elsewhere and normalize codes to uppercase strings
          const countryOptions = response.data.map((c: any) => ({
            value: c.id,
            label: c.name,
            // normalize code to uppercase string (guard null/undefined)
            code: String(c.code ?? c.shortCode ?? "").toUpperCase(),
            name: c.name,
            id: c.id,
          }));
          setCountries(countryOptions);
        }
      } catch (error) {
        console.error("Error fetching countries:", error);
      }
    };
    fetchCountries();
  }, []);

  // Extracted fetchRates so we can call it from event handler too
  const fetchRates = async () => {
    setIsLoading(true);
    try {
      // Check if minimal step1 data exists
      if (!createOrderData?.step1) {
        console.log(
          "Step1 data not ready yet for rates:",
          createOrderData?.step1,
        );
        return;
      }

      // require at least country + city info to fetch rates reliably
      if (
        !createOrderData.step1.fromCountry ||
        !createOrderData.step1.toCountry ||
        !createOrderData.step1.fromCity ||
        !createOrderData.step1.toCity
      ) {
        console.warn(
          "Insufficient Step1 location data for rates. fromCountry/toCountry/fromCity/toCity required.",
          createOrderData.step1,
        );
        return;
      }

      const step1 = createOrderData?.step1;

      // Calculate total weight from all packages
      const totalWeight =
        step1.package_details?.reduce(
          (sum: number, pkg: any) => sum + (parseFloat(pkg.weight) || 0),
          0,
        ) || 0;

      // Resolve origin/destination country codes robustly:
      const resolveCountryCodeFromRef = (ref: any) => {
        if (!ref) return null;
        // preferred code field
        if (ref.code && typeof ref.code === "string") return ref.code;
        // sometimes object has shortCode / shortcode
        if (ref.shortCode && typeof ref.shortCode === "string")
          return ref.shortCode;
        // if ref.value is an id, try lookup from fetched countries list
        const id = ref.value ?? ref.id ?? null;
        if (id && countries.length > 0) {
          const found = countries.find(
            (c: any) => c.id === id || c.value === id,
          );
          if (found) return found.code ?? found.shortCode ?? null;
        }
        // try alternative fields on step1 (snake_case)
        if (ref.country_code && typeof ref.country_code === "string")
          return ref.country_code;
        return null;
      };

      let originCountryCode = resolveCountryCodeFromRef(step1.fromCountry);
      let destinationCountryCode = resolveCountryCodeFromRef(step1.toCountry);

      // If codes still missing, don't fetch rates with wrong defaults — abort and warn.
      if (!originCountryCode || !destinationCountryCode) {
        console.warn(
          "Unable to resolve origin/destination country codes for rates. Aborting fetchRates.",
          { originCountryCode, destinationCountryCode, step1 },
        );
        return;
      }

      // ensure they are strings
      originCountryCode = String(originCountryCode);
      destinationCountryCode = String(destinationCountryCode);

      const payload = {
        origin_country: originCountryCode,
        origin_city: step1.fromCity?.name || "",
        origin_postal_code: "",
        destination_country: destinationCountryCode,
        destination_city: step1.toCity?.name || "",
        destination_postal_code: "",
        weight: totalWeight > 0 ? totalWeight : 0.1,
        number_of_pieces: step1.noOfPackages || 1,
        product_group: step1.shipmentContent === "Document" ? "DOC" : "EXP",
        product_type: step1.shipmentContent === "Document" ? "OND" : "PPX",
        length: parseFloat(step1.package_details?.[0]?.length) || 10,
        width: parseFloat(step1.package_details?.[0]?.width) || 10,
        height: parseFloat(step1.package_details?.[0]?.height) || 10,
      };

      const response = await getAllShippingRates(payload);
      if (response.status && response.data?.rates) {
        const rates = response.data.rates;

        // Find the cheapest rate to add a badge
        const cheapestAmount = Math.min(...rates.map((r: any) => r.amount));

        const groupedCarriers: any[] = [];

        const getCarrierGroup = (carrierName: string) => {
          let group = groupedCarriers.find(
            (c) => c.id === carrierName.toLowerCase(),
          );
          if (!group) {
            group = {
              id: carrierName.toLowerCase(),
              name: carrierName,
              logo: getCarrierLogo(carrierName),
              color: getCarrierColor(carrierName),
              services: [],
            };
            groupedCarriers.push(group);
          }
          return group;
        };

        rates.forEach((rate: any) => {
          const group = getCarrierGroup(rate.carrier);

          // Format delivery date/days
          let deliveryInfo = rate.delivery_date || "N/A";
          if (!rate.delivery_date && rate.delivery_days > 0) {
            deliveryInfo = `${rate.delivery_days} ${rate.delivery_days === 1 ? "Day" : "Days"}`;
          } else if (!rate.delivery_date && rate.delivery_days === 0) {
            deliveryInfo = "Standard Delivery";
          }

          group.services.push({
            id: rate.service_code || `${rate.carrier}-${rate.service_name}`,
            name: rate.service_name,
            deliveryDate: deliveryInfo,
            price: rate.amount,
            currency: rate.currency,
            badge: rate.amount === cheapestAmount ? "Cheapest" : undefined,
            details: rate.details, // Store full details for later use if needed
          });
        });

        setCarriers(groupedCarriers);
      }
    } catch (error) {
      console.error("Error fetching rates:", error);
    } finally {
      setIsLoading(false);
    }
  };

  // run fetchRates when step1Data or countries update
  useEffect(() => {
    fetchRates();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [createOrderData?.step1, countries]);

  // restore selected service after carriers load if Redux has saved selection
  useEffect(() => {
    if (carriers.length > 0 && createOrderData?.step2?.selectedServiceId) {
      setSelectedServiceId(createOrderData.step2.selectedServiceId);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [carriers]);

  // listen for navigation events so parent components can request reload/restore
  useEffect(() => {
    const handler = (e: any) => {
      try {
        const detail = e?.detail || {};
        if (detail?.step === 2) {
          // If reload requested, re-run rate fetch and restore selection
          if (detail?.reload) {
            fetchRates().then(() => {
              if (createOrderData?.step2?.selectedServiceId) {
                setSelectedServiceId(createOrderData.step2.selectedServiceId);
              }
            });
          } else {
            // just restore selection if carriers already loaded
            if (createOrderData?.step2?.selectedServiceId) {
              setSelectedServiceId(createOrderData.step2.selectedServiceId);
            }
          }
        }
      } catch (err) {
        console.error("Navigation event handler error:", err);
      }
    };
    window.addEventListener("navigate-to-step", handler);
    return () => window.removeEventListener("navigate-to-step", handler);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [createOrderData?.step2, carriers]);

  const getCarrierLogo = (name: string) => {
    if (name.toLowerCase().includes("dhl"))
      return "/images/international/dhl-express-logo.png";
    if (name.toLowerCase().includes("fedex"))
      return "/images/international/fedex-logo.png";
    if (name.toLowerCase().includes("aramex"))
      return "/images/international/aramex-logo.png";
    if (name.toLowerCase().includes("smsa"))
      return "/images/international/smsa.jpg";
    return "";
  };

  const getCarrierColor = (name: string) => {
    if (name.toLowerCase().includes("dhl")) return "#FFCC00";
    if (name.toLowerCase().includes("fedex")) return "#4D148C";
    if (name.toLowerCase().includes("aramex")) return "#EF3340";
    if (name.toLowerCase().includes("smsa")) return "#F37021";
    return "#000";
  };

  const handleServiceSelect = (serviceId: string) => {
    setSelectedServiceId(serviceId);
  };

  const validateStep2 = async () => {
    if (!selectedServiceId) {
      // toast.error("Please select a shipment service");
      return false;
    }

    let selectedService: any = null;
    let selectedCarrier: any = null;

    for (const carrier of carriers) {
      const service = carrier.services.find(
        (s: any) => s.id === selectedServiceId,
      );
      if (service) {
        selectedService = service;
        selectedCarrier = carrier;
        break;
      }
    }

    // Compute robust draft id fallback
    const draftId =
      step1Data?.draft_order_id ??
      step1Data?.draftOrderId ??
      step1Data?.draft_order?.id ??
      step1Data?.id ??
      null;

    if (!draftId) {
      console.warn("Draft order id not found on step1Data:", step1Data);
      // still proceed but backend may reject - warn for debugging
    } else {
      console.log("Using draft id:", draftId);
    }

    // Compute total weight from packages if available (same logic as rates fetch)
    const totalWeight =
      step1Data?.package_details?.reduce(
        (sum: number, pkg: any) => sum + (parseFloat(pkg.weight) || 0),
        0,
      ) || 0;

    // Safely determine number of pieces
    const numberOfPieces =
      step1Data?.noOfPackages ??
      step1Data?.no_of_packages ??
      step1Data?.number_of_pieces ??
      1;

    // Prepare payload with robust fallbacks and include both id and draft_order_id
    const payload = {
      // include multiple keys to ensure backend receives the draft identifier
      id: draftId,
      draft_order_id: draftId,
      from_country_id:
        step1Data?.fromCountry?.value ?? step1Data?.from_country_id,
      to_country_id: step1Data?.toCountry?.value ?? step1Data?.to_country_id,
      from_city_id: step1Data?.fromCity?.value ?? step1Data?.from_city_id,
      to_city_id: step1Data?.toCity?.value ?? step1Data?.to_city_id,
      shipment_content:
        step1Data?.shipmentContent ?? step1Data?.shipment_content,
      no_of_packages: numberOfPieces,
      total_weight:
        totalWeight > 0 ? totalWeight : (step1Data?.total_weight ?? 0.1),
      total_value: step1Data?.total_value ?? 0,
      package_details: (step1Data?.package_details || []).map((pkg: any) => ({
        weight: parseFloat(pkg.weight) || 0,
        length: parseFloat(pkg.length) || 0,
        width: parseFloat(pkg.width) || 0,
        height: parseFloat(pkg.height) || 0,
        package_description: pkg.package_description || pkg.description || "",
        customer_input_package_value:
          parseFloat(pkg.customer_input_package_value) ||
          parseFloat(pkg.package_value) ||
          0,
      })),
      // New fields for Step 2
      carrier: selectedCarrier?.name ?? selectedCarrier?.id ?? "",
      // service_code: selectedService?.id ?? selectedService?.service_code ?? "",
      service_code: selectedServiceId ?? "",
      service_name: selectedService?.name ?? "",
      shipping_charge: selectedService?.price ?? selectedService?.amount ?? 0,
      currency: selectedService?.currency ?? currencyName,
    };

    console.log("Validate Step2 payload:", JSON.stringify(payload, null, 2));

    try {
      setIsLoading(true);
      const response = await initiateInternationalDraftOrder(payload);
      if (response?.status) {
        // Save selected service info back to parent/store
        onSave({
          selectedServiceId,
          selectedServiceDetails: selectedService,
          selectedCarrierDetails: {
            id: selectedCarrier?.id,
            name: selectedCarrier?.name,
            logo: selectedCarrier?.logo,
          },
        });
        return true;
      } else {
        console.error("Failed to update draft:", response?.message, response);
        return false;
      }
    } catch (error) {
      console.error("Error updating draft:", error);
      return false;
    } finally {
      setIsLoading(false);
    }
  };

  return (
    <>
      <div className="scrollWrap step2-international p-4 bg-light-gray">
        <div className="mb-4 d-flex justify-content-between align-items-center">
          <h5 className="font-16 font-700">
            Select Shipment Service (
            {isLoading
              ? "..."
              : carriers
                  .reduce((sum, c) => sum + c.services.length, 0)
                  .toString()
                  .padStart(2, "0")}
            )
          </h5>
          <div className="font-10 text-muted">
            <span className="text-danger">*</span> Final charges may slightly
            vary based on international courier rates
          </div>
        </div>

        {isLoading ? (
          <div className="row g-4">
            {[1, 2, 3].map((i) => (
              <div key={i} className="col-lg-4 col-md-6">
                <ServiceCardSkeleton />
              </div>
            ))}
          </div>
        ) : carriers.length === 0 ? (
          <div
            className="d-flex justify-content-center align-items-center"
            style={{ minHeight: "400px" }}
          >
            <div
              className="text-center p-5 bg-white rounded-4 shadow-sm"
              style={{ maxWidth: "550px", width: "100%" }}
            >
              <div className="mb-4">
                <img
                  src="/images/app/no-data.webp"
                  alt="No Services Found"
                  className="img-fluid"
                  style={{ maxWidth: "240px", opacity: 0.9 }}
                />
              </div>
              <h4 className="fw-bold mb-3 text-dark">
                No Shipping Services Found
              </h4>
              <p className="text-muted mb-4 fs-6">
                We couldn&apos;t find any carriers for the selected route and
                package details. <br className="d-none d-md-block" />
                Please try adjusting your shipment details to see available
                options.
              </p>
              <button
                className="btn delybell-primary px-4 py-2 fw-semibold d-inline-flex align-items-center gap-2"
                style={{ borderRadius: "8px", transition: "all 0.2s" }}
                onClick={() => {
                  setStep(1);
                  try {
                    window.dispatchEvent(
                      new CustomEvent("navigate-to-step", {
                        detail: { step: 1, reload: true },
                      }),
                    );
                    // eslint-disable-next-line @typescript-eslint/no-unused-vars
                  } catch (err: any) {
                    /* ignore */
                  }
                }}
              >
                <i className="ri-arrow-left-line fs-5"></i>
                <span>Edit Shipment Details</span>
              </button>
            </div>
          </div>
        ) : (
          <div className="row g-4">
            {carriers.map((carrier) => (
              <div key={carrier.id} className="col-lg-4 col-md-6">
                <ServiceCard
                  logo={carrier.logo}
                  carrierName={carrier.name}
                  services={carrier.services}
                  selectedServiceId={selectedServiceId}
                  onSelect={handleServiceSelect}
                  color={carrier.color}
                />
              </div>
            ))}
          </div>
        )}
      </div>

      <CreateOrderFooter
        step={step}
        setStep={async (nextStep) => {
          if (await validateStep2()) setStep(nextStep);
        }}
        validation={validateStep2}
        backButton={true}
        backButtonFn={() => {
          setStep(1);
          try {
            window.dispatchEvent(
              new CustomEvent("navigate-to-step", {
                detail: { step: 1, reload: true },
              }),
            );
            // eslint-disable-next-line @typescript-eslint/no-unused-vars
          } catch (err) {
            /* ignore */
          }
        }}
        defaultOrderDetails={defaultOrderDetails}
        isEditMode={isEditMode}
        isInternational={true}
      />
      <style jsx>{`
        .bg-light-gray {
          background-color: #f8f9fa;
        }
      `}</style>
    </>
  );
};

export default Step2;
