import { api } from "@/services/api";
import type { Freight } from "@edr/types";
import { useQuery } from "@tanstack/react-query";
import { CalendarClock, FileText, Layers, RefreshCw } from "lucide-react";
import { useMemo, useState } from "react";
import { Controller, type UseFormReturn } from "react-hook-form";
import { BookingFormInputValues, type BookingFormValues } from "./schema";
import {
  AlertBox,
  AsyncComboboxField,
  OptionCard,
  OptionFieldError,
  StepCard,
  StepHeader,
} from "./shared";
import { FileSignature } from "lucide-react";
import { Divider, Stack, Text } from "@mantine/core";

type BookingForm = UseFormReturn<
  BookingFormInputValues,
  any,
  BookingFormValues
>;

interface PreviousContractOption {
  value: string;
  label: string;
  booking: Freight.IBooking;
}

export function Step1ContractType({
  form,
  referenceData,
}: {
  form: BookingForm;
  referenceData?: Freight.BookingReferenceData;
}) {
  const contractType = form.watch("contractType");
  const previousContractRef = form.watch("previousContractRef");
  const [searchQuery, setSearchQuery] = useState("");

  const {
    data: bookings,
    isLoading,
    error,
  } = useQuery(
    api.bookings.list.queryOptions({
      input: {
        page: 1,
        pageSize: 100,
        sortBy: "createdAt",
        sortOrder: "DESC",
      },
    }),
  );

  const contractOptions = useMemo<PreviousContractOption[]>(() => {
    if (!bookings) return [];

    return bookings?.items
      .map((booking) => {
        const origin = booking.originYard?.label || "Unknown";
        const destination = booking.destinationYard?.label || "Unknown";
        return {
          value: booking.id,
          label: `${booking.reference} - Route: ${origin} to ${destination}`,
          booking,
        };
      })
      .filter((opt) =>
        opt.label.toLowerCase().includes(searchQuery.toLowerCase()),
      );
  }, [bookings, searchQuery]);

  const handleSelectContract = (contractId: string) => {
    const selected = contractOptions.find((opt) => opt.value === contractId);
    if (!selected) return;

    form.setValue("previousContractRef", contractId);

    const booking = selected.booking;
    if (!booking) return;

    // ── Service type ────────────────────────────────────────────────────
    const service = booking.serviceType
      ? referenceData?.service.find((s) => s.code === booking.serviceType)
      : undefined;
    const serviceId = service?.id || booking.serviceTypeId;
    if (serviceId) form.setValue("serviceTypeId", serviceId);

    // ── First / last mile (address + map coordinates) ───────────────────
    form.setValue("firstMile", {
      enabled: booking.firstMileEnabled,
      pickUpAddress: booking.firstMilePickupAddress ?? "",
      lat: booking.firstMilePickupLat ?? null,
      lng: booking.firstMilePickupLng ?? null,
    });
    form.setValue("lastMile", {
      enabled: booking.lastMileEnabled,
      deliveryAddress: booking.lastMileDeliveryAddress ?? "",
      lat: booking.lastMileDeliveryLat ?? null,
      lng: booking.lastMileDeliveryLng ?? null,
    });

    // ── Equipment return ────────────────────────────────────────────────
    form.setValue(
      "equipmentReturn",
      booking.equipmentReturn === "WITH_RETURN"
        ? "with_return"
        : "without_return",
    );

    // ── Customs ─────────────────────────────────────────────────────────
    form.setValue(
      "customsClearingEnabled",
      booking.customsClearingEnabled ?? service?.includesCustoms ?? false,
    );
    form.setValue("customsClearingAgent", booking.customsClearingAgent ?? "");

    // ── Route ───────────────────────────────────────────────────────────
    if (booking.originYard?.id) {
      form.setValue("originYard", booking.originYard.id);
    }
    if (booking.destinationYard?.id) {
      form.setValue("destinationYard", booking.destinationYard.id);
    }

    // ── Cargo type ──────────────────────────────────────────────────────
    form.setValue(
      "cargoType",
      booking.freightType === "CONTAINER" ? "container" : "bulk",
    );

    // ── Cargo weight (bulk) ─────────────────────────────────────────────
    // Carry the prior amount into both the cargo-step weight (one-time path)
    // and the primary route quantity (general-contract path) so whichever input
    // is shown is prefilled.
    if (booking.cargoTotalWeightVgm > 0) {
      form.setValue("cargoWeight", String(booking.cargoTotalWeightVgm));
      form.setValue(
        "primaryRouteQuantity",
        String(booking.cargoTotalWeightVgm),
      );
    }

    // ── Hazardous / refrigerated ────────────────────────────────────────
    form.setValue("isHazardous", booking.isHazardous);
    form.setValue("isRefrigerated", booking.isRefrigerated);

    // ── Containers ──────────────────────────────────────────────────────
    if (
      booking.freightType === "CONTAINER" &&
      booking.containers &&
      booking.containers.length > 0
    ) {
      const mappedContainers = booking.containers.map((c) => {
        let containerTypeName = "";
        for (const group of referenceData?.containers ?? []) {
          const ct = group.types.find(
            (t) => t.code === c.type || t.name === c.type,
          );
          if (ct) {
            containerTypeName = ct.name;
            break;
          }
        }
        return {
          type: (c.type === "40ft" ? "40ft" : "20ft") as "20ft" | "40ft",
          containerType: containerTypeName,
          qty: String(c.qty),
          vgm: String(c.vgm),
        };
      });
      form.setValue("containers", mappedContainers);
    }

    // Consolidation is system-managed (always allowed) — not copied from the
    // previous booking and not customer-controllable.

    // ── Scheduled date ──────────────────────────────────────────────────
    if (booking.scheduledDate) {
      form.setValue("scheduledDate", booking.scheduledDate);
    }
  };

  return (
    <StepCard>
      <StepHeader
        icon={<FileSignature size={22} />}
        title="Booking Type"
        description="Choose a one-time shipment or a general contract you can draw down from over time."
      />

      <Controller
        name="bookingType"
        control={form.control}
        render={({ field }) => (
          <div className="grid gap-4 md:grid-cols-2">
            <OptionCard
              selected={field.value !== "general_contract"}
              icon={<CalendarClock className="h-5 w-5" />}
              iconBg="#ECF6F1"
              iconColor="#0A6F4D"
              title="One-Time Booking"
              description="A single shipment with a chosen ship date — the standard flow."
              onClick={() => field.onChange("one_time")}
            />
            <OptionCard
              selected={field.value === "general_contract"}
              icon={<Layers className="h-5 w-5" />}
              iconBg="#F1ECFB"
              iconColor="#6A40B8"
              title="General Contract"
              description="Reserve a total quantity once, then place multiple orders against it until it runs out."
              onClick={() => field.onChange("general_contract")}
            />
          </div>
        )}
      />

      <Divider my={24} />

      <Text fw={700} fz={15} mb={4} style={{ color: "#10202F" }}>
        Contract Type
      </Text>
      <Text fz={13} c="edr-muted" mb={16}>
        Start a fresh contract or renew an existing one to reuse its details.
      </Text>

      <Controller
        name="contractType"
        control={form.control}
        render={({ field, fieldState }) => (
          <div>
            <div className="grid gap-4 md:grid-cols-2">
              <OptionCard
                selected={field.value === "new"}
                icon={<FileText className="h-5 w-5" />}
                iconBg="#ECF6F1"
                iconColor="#0A6F4D"
                title="New Contract"
                description="Create a fresh freight contract from scratch."
                onClick={() => {
                  field.onChange("new");
                  form.clearErrors(["contractType", "previousContractRef"]);
                  form.setValue("previousContractRef", "");
                }}
              />

              <OptionCard
                selected={field.value === "renewal"}
                icon={<RefreshCw className="h-5 w-5" />}
                iconBg="#EAF1FB"
                iconColor="#2E5B96"
                title="Contract Renewal"
                description="Pick a previous reference to auto-fill historical parameters."
                onClick={() => {
                  field.onChange("renewal");
                  form.clearErrors("contractType");
                }}
              />
            </div>
            <OptionFieldError error={fieldState.error} />
          </div>
        )}
      />

      {contractType === "renewal" && (
        <Stack gap={12} mt={22}>
          {error && (
            <AlertBox tone="error">
              Failed to load previous contracts. Please try again later.
            </AlertBox>
          )}
          <Controller
            name="previousContractRef"
            control={form.control}
            render={({ field, fieldState }) => (
              <AsyncComboboxField
                field={field}
                error={fieldState.error}
                label="Previous Contract Reference Number"
                placeholder="Search by reference or route..."
                options={contractOptions}
                isLoading={isLoading}
                searchQuery={searchQuery}
                onSearchChange={setSearchQuery}
                onSelect={handleSelectContract}
              />
            )}
          />
          {previousContractRef && (
            <AlertBox tone="success">
              <strong>Contract found.</strong> Route, service type, and cargo
              details will be pre-filled.
            </AlertBox>
          )}
        </Stack>
      )}
    </StepCard>
  );
}
