import { api } from "@/services/api";
import type { Freight } from "@edr/types";
import { useQuery } from "@tanstack/react-query";
import { useMemo, useState } from "react";
import { Controller, type UseFormReturn } from "react-hook-form";
import { Badge, Group, Select, Stack, Text } from "@mantine/core";
import {
  CONTRACT_KIND_OPTIONS,
  ContractFormInputValues,
  OPERATION_TYPE_OPTIONS,
  type ContractFormValues,
  type OperationType,
} from "./schema";
import { AlertBox, AsyncComboboxField, fieldStyles } from "./shared";

const CONTRACT_TYPE_OPTIONS = [
  { value: "new", label: "New Contract" },
  // Renewal is disabled for now — not yet available to customers.
  { value: "renewal", label: "Contract Renewal (coming soon)", disabled: true },
];

type ContractForm = UseFormReturn<
  ContractFormInputValues,
  any,
  ContractFormValues
>;

interface PreviousContractOption {
  value: string;
  label: string;
  contract: Freight.IContract;
}

export function Step1ContractType({
  form,
  referenceData,
  allowedOperations,
  onOperationSelect,
  operationStatus,
}: {
  form: ContractForm;
  referenceData?: Freight.BookingReferenceData;
  allowedOperations: OperationType[];
  onOperationSelect?: (op: OperationType) => void;
  /** Approval state of the profile each operation maps to (for the badges). */
  operationStatus?: (
    op: OperationType,
  ) => "approved" | "pending" | "rejected" | "suspended" | "missing";
}) {
  const contractType = form.watch("contractType");

  const operationData = OPERATION_TYPE_OPTIONS.filter((opt) =>
    allowedOperations.includes(opt.value),
  ).map((opt) => ({
    value: opt.value,
    label: opt.label,
    disabled: opt.disabled ?? false,
  }));
  const previousContractRef = form.watch("previousContractRef");
  const [searchQuery, setSearchQuery] = useState("");

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

  const contractOptions = useMemo<PreviousContractOption[]>(() => {
    if (!contracts) return [];
    return contracts.items
      .map((contract) => {
        const route = contract.routes?.[0];
        const origin = route?.originYard?.label ?? "Unknown";
        const destination = route?.destinationYard?.label ?? "Unknown";
        return {
          value: contract.reference,
          label: `${contract.reference} - Route: ${origin} to ${destination}`,
          contract,
        };
      })
      .filter((opt) =>
        opt.label.toLowerCase().includes(searchQuery.toLowerCase()),
      );
  }, [contracts, searchQuery]);

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

    form.setValue("previousContractRef", reference);

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

    // ── Service type ──
    const serviceId = contract.serviceTypeId;
    if (serviceId) form.setValue("serviceTypeId", serviceId);

    // ── First / last mile ──
    form.setValue("firstMile", {
      enabled: Boolean(contract.firstMilePickupAddress),
      pickUpAddress: contract.firstMilePickupAddress ?? "",
      lat: contract.firstMilePickupLat ?? null,
      lng: contract.firstMilePickupLng ?? null,
    });
    form.setValue("lastMile", {
      enabled: Boolean(contract.lastMileDeliveryAddress),
      deliveryAddress: contract.lastMileDeliveryAddress ?? "",
      lat: contract.lastMileDeliveryLat ?? null,
      lng: contract.lastMileDeliveryLng ?? null,
    });

    // ── Equipment return / customs ──
    // Stored uppercase on the contract (WITH_RETURN / WITHOUT_RETURN).
    form.setValue(
      "equipmentReturn",
      (contract.equipmentReturn ?? "").toUpperCase() === "WITH_RETURN"
        ? "with_return"
        : "without_return",
    );
    form.setValue(
      "customsClearingEnabled",
      contract.customsClearingEnabled ?? false,
    );
    form.setValue("customsClearingAgent", contract.customsClearingAgent ?? "");

    // ── Route (single route per contract) ──
    const routes = contract.routes ?? [];
    if (routes[0]) {
      form.setValue("originYard", routes[0].originYardId);
      form.setValue("destinationYard", routes[0].destinationYardId);
    }

    // ── Cargo scope ──
    form.setValue(
      "cargoType",
      contract.freightType === "BULK" ? "bulk" : "container",
    );
    const scope = contract.cargoScope ?? [];
    // Contracts always cover both sizes now — even when renewing an older
    // single-size contract.
    if (contract.freightType !== "BULK") {
      form.setValue("enabledContainerSizes", ["20ft", "40ft"]);
    }
    const bulkScope = scope.find((s) => s.cargoTypeId);
    if (bulkScope?.cargoTypeId) {
      // Find the parent group for this commodity so the cascader prefills.
      const tree = referenceData?.cargo_type ?? [];
      for (const group of tree) {
        const child = group.children?.find(
          (c) => c.id === bulkScope.cargoTypeId,
        );
        if (child) {
          form.setValue("cargoTypePath", [group.id, child.id]);
          break;
        }
      }
      if (bulkScope.cargoFreeText) {
        form.setValue("cargoFreeText", bulkScope.cargoFreeText);
      }
    }

    // ── Flags ──
    form.setValue("isHazardous", contract.isHazardous);
    form.setValue("isRefrigerated", contract.isReefer);
  };

  return (
    <Stack gap={16}>
      {allowedOperations.length === 0 && (
        <AlertBox tone="error">
          Your company has no operational profile yet. Complete onboarding to
          register as an importer, exporter, or freight forwarder.
        </AlertBox>
      )}

      {/* Operation Type + Contract Kind + New/Renewal on one wrapping row. Each
          field keeps a sensible min width and flexes to fill / wrap below on
          narrow screens. */}
      <div className="flex flex-wrap gap-4">
        <Controller
          name="operationType"
          control={form.control}
          render={({ field, fieldState }) => (
            <Select
              className="flex-1 min-w-[200px]"
              label="Operation Type *"
              placeholder="Select an operation…"
              data={operationData}
              value={field.value || null}
              onChange={(v) => {
                if (!v) return;
                field.onChange(v);
                onOperationSelect?.(v as OperationType);
              }}
              onBlur={field.onBlur}
              error={fieldState.error?.message}
              allowDeselect={false}
              radius={10}
              checkIconPosition="right"
              comboboxProps={{ withinPortal: true, shadow: "md", radius: "md" }}
              styles={fieldStyles}
              renderOption={({ option }) => {
                const status = operationStatus?.(option.value as OperationType);
                return (
                  <Group justify="space-between" gap="sm" wrap="nowrap" w="100%">
                    <Text fz={14}>{option.label}</Text>
                    {status === "pending" && (
                      <Badge size="xs" color="yellow" variant="light" radius="sm">
                        Pending
                      </Badge>
                    )}
                    {status === "rejected" && (
                      <Badge size="xs" color="red" variant="light" radius="sm">
                        Rejected
                      </Badge>
                    )}
                    {status === "suspended" && (
                      <Badge size="xs" color="orange" variant="light" radius="sm">
                        Suspended
                      </Badge>
                    )}
                    {status === "missing" && (
                      <Badge size="xs" color="gray" variant="light" radius="sm">
                        Add license
                      </Badge>
                    )}
                  </Group>
                );
              }}
            />
          )}
        />

        <Controller
          name="contractKind"
          control={form.control}
          render={({ field }) => (
            <Select
              className="flex-1 min-w-[200px]"
              label="Contract Kind *"
              data={CONTRACT_KIND_OPTIONS.map((o) => ({
                value: o.value,
                label: o.label,
              }))}
              value={field.value ?? "one_time"}
              onChange={(v) => field.onChange(v ?? "one_time")}
              allowDeselect={false}
              radius={10}
              checkIconPosition="right"
              comboboxProps={{ withinPortal: true, shadow: "md", radius: "md" }}
              styles={fieldStyles}
            />
          )}
        />

        <Controller
          name="contractType"
          control={form.control}
          render={({ field, fieldState }) => (
            <Select
              className="flex-1 min-w-[200px]"
              label="New or Renewal *"
              placeholder="Select…"
              data={CONTRACT_TYPE_OPTIONS}
              value={field.value || null}
              onChange={(v) => {
                if (!v) return;
                field.onChange(v);
                form.clearErrors("contractType");
                if (v === "new") {
                  form.clearErrors("previousContractRef");
                  form.setValue("previousContractRef", "");
                }
              }}
              onBlur={field.onBlur}
              error={fieldState.error?.message}
              allowDeselect={false}
              radius={10}
              checkIconPosition="right"
              comboboxProps={{ withinPortal: true, shadow: "md", radius: "md" }}
              styles={fieldStyles}
            />
          )}
        />
      </div>

      {contractType === "renewal" && (
        <Stack gap={12}>
          {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
              scope will be pre-filled.
            </AlertBox>
          )}
        </Stack>
      )}
    </Stack>
  );
}
