import { Box, Group, Stack, Switch, Text, TextInput } from "@mantine/core";
import type { ReactNode } from "react";
import { Check, FileText, Info, Layers, Train, Truck } from "lucide-react";
import { useEffect, useRef } from "react";
import { Controller, type UseFormReturn } from "react-hook-form";
import { BookingFormInputValues, type BookingFormValues, filterBookableServices } from "./schema";
import {
  fieldStyles,
  OptionFieldError,
  StepCard,
  StepHeader,
  StepLabel,
} from "./shared";
import { PaymentCurrencyField } from "./payment-currency-field";
import { LocationPicker } from "./LocationPicker";

import type { Freight } from "@edr/types";

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

export function Step2ServiceType({
  form,
  referenceData,
}: {
  form: BookingForm;

  referenceData?: Freight.BookingReferenceData;
}) {
  const serviceTypeId = form.watch("serviceTypeId");
  const operationType = form.watch("operationType");
  const serviceType = referenceData?.service.find(
    (s) => s.id === serviceTypeId,
  );

  const { includesCustoms, includesFirstMile, includesLastMile } =
    serviceType ?? {};
  const firstMileEnabled = form.watch("firstMile.enabled");
  const lastMileEnabled = form.watch("lastMile.enabled");

  const prevServiceType = useRef(serviceType);
  // Only clear a mile when the current service doesn't include it — this ran
  // unconditionally before, so it wiped an already-entered (or prefilled, or
  // draft-restored) pickup/delivery address on every service change, even one
  // that still includes that mile.
  useEffect(() => {
    if (includesFirstMile) return;
    form.setValue(
      "firstMile",
      { enabled: false, pickUpAddress: "", lat: null, lng: null },
      { shouldValidate: true },
    );
  }, [includesFirstMile, form]);

  useEffect(() => {
    if (includesLastMile) return;
    form.setValue(
      "lastMile",
      { enabled: false, deliveryAddress: "", lat: null, lng: null },
      { shouldValidate: true },
    );
  }, [includesLastMile, form]);

  useEffect(() => {
    const prev = prevServiceType.current;
    prevServiceType.current = serviceType;

    if (!prev || prev === serviceType) return;

    if (includesCustoms) {
      form.setValue("customsClearingEnabled", true, { shouldDirty: true });
      form.setValue("customsClearingAgent", "", { shouldDirty: true });
    } else {
      form.setValue("customsClearingEnabled", false, { shouldDirty: true });
      form.setValue("customsClearingAgent", "", { shouldDirty: true });
    }
  }, [serviceTypeId, form]);

  const showServiceSections =
    serviceType != null || includesFirstMile || includesLastMile;

  const bookableServices = filterBookableServices(
    referenceData?.service,
    operationType,
  );

  useEffect(() => {
    // Skip right after a hydration `form.reset()` (draft restore / renewal
    // prefill) — a restored selection is trusted as-is until the customer
    // actually changes something live.
    if (!form.formState.isDirty) return;
    const currentId = form.getValues("serviceTypeId");
    if (!currentId) return;
    if (!bookableServices.some((s) => s.id === currentId)) {
      form.setValue("serviceTypeId", "", { shouldValidate: true });
    }
  }, [operationType, bookableServices, form]);

  return (
    <StepCard>
      <StepHeader
        icon={<Layers size={22} />}
        title="Service Type"
        description="Choose the service combination, then configure your trucking options."
      />

      <Controller
        name="serviceTypeId"
        control={form.control}
        render={({ field, fieldState }) => (
          <div>
            <div className="grid gap-3 sm:grid-cols-2">
              {bookableServices.map((s) => (
                  <ServiceTypeCard
                    key={s.id}
                    selected={field.value === s.id}
                    onClick={() => field.onChange(s.id)}
                    title={s.serviceName}
                    description={s.description}
                  />
                ))}
            </div>
            <OptionFieldError error={fieldState.error} />
          </div>
        )}
      />

      <PaymentCurrencyField control={form.control} />

      {showServiceSections && (
        <Stack gap={12} mt={24}>
          <StepLabel>Trucking & customs options</StepLabel>
          {/* First Mile */}
          {includesFirstMile && (
            <Controller
              name="firstMile.enabled"
              control={form.control}
              render={({ field }) => (
                <ServiceToggle
                  icon={<Truck size={18} />}
                  title="First Mile — Pick-up"
                  description="Truck pick-up from your premises (Door to Port) to the origin rail yard."
                  checked={field.value ?? false}
                  onChange={(value) => {
                    field.onChange(value);
                    if (!value) {
                      // Toggling off clears the captured pick-up location below.
                      form.setValue(
                        "firstMile",
                        { enabled: false, pickUpAddress: "", lat: null, lng: null },
                        { shouldDirty: true, shouldValidate: true },
                      );
                    }
                  }}
                >
                  {firstMileEnabled && (
                    <Box mt="md">
                      <Controller
                        name="firstMile"
                        control={form.control}
                        render={({ field: mf, fieldState }) => (
                          <LocationPicker
                            label="Pick-up location"
                            placeholder="Search the pick-up address…"
                            error={
                              (
                                fieldState.error as {
                                  pickUpAddress?: { message?: string };
                                }
                              )?.pickUpAddress?.message
                            }
                            value={{
                              address: mf.value?.pickUpAddress ?? "",
                              lat: mf.value?.lat ?? null,
                              lng: mf.value?.lng ?? null,
                            }}
                            onChange={(loc) =>
                              mf.onChange({
                                ...mf.value,
                                enabled: true,
                                pickUpAddress: loc.address,
                                lat: loc.lat,
                                lng: loc.lng,
                              })
                            }
                          />
                        )}
                      />
                    </Box>
                  )}
                </ServiceToggle>
              )}
            />
          )}

          {/* Last Mile */}
          {includesLastMile && (
            <Controller
              name="lastMile.enabled"
              control={form.control}
              render={({ field }) => (
                <ServiceToggle
                  icon={<Truck size={18} />}
                  title="Last Mile — Delivery"
                  description="Truck delivery from the destination rail yard to the final address (Port to Door)."
                  checked={field.value ?? false}
                  onChange={(value) => {
                    field.onChange(value);
                    if (!value) {
                      // Toggling off clears the captured delivery location below.
                      form.setValue(
                        "lastMile",
                        { enabled: false, deliveryAddress: "", lat: null, lng: null },
                        { shouldDirty: true, shouldValidate: true },
                      );
                      form.setValue("equipmentReturn", "with_return", {
                        shouldDirty: true,
                      });
                    }
                  }}
                >
                  {lastMileEnabled && (
                    <Box mt="md">
                      <Controller
                        name="lastMile"
                        control={form.control}
                        render={({ field: mf, fieldState }) => (
                          <LocationPicker
                            label="Delivery location"
                            placeholder="Search the delivery address…"
                            error={
                              (
                                fieldState.error as {
                                  deliveryAddress?: { message?: string };
                                }
                              )?.deliveryAddress?.message
                            }
                            value={{
                              address: mf.value?.deliveryAddress ?? "",
                              lat: mf.value?.lat ?? null,
                              lng: mf.value?.lng ?? null,
                            }}
                            onChange={(loc) =>
                              mf.onChange({
                                ...mf.value,
                                enabled: true,
                                deliveryAddress: loc.address,
                                lat: loc.lat,
                                lng: loc.lng,
                              })
                            }
                          />
                        )}
                      />
                    </Box>
                  )}
                </ServiceToggle>
              )}
            />
          )}

          {/* Equipment Return */}
          {includesLastMile && lastMileEnabled && (
            <Controller
              name="equipmentReturn"
              control={form.control}
              render={({ field }) => (
                <ServiceToggle
                  icon={<Truck size={18} />}
                  title="Equipment Return"
                  description={
                    field.value === "with_return"
                      ? "Container returned to EDR after unloading."
                      : "Container retained by the customer after delivery."
                  }
                  checked={field.value === "with_return"}
                  onChange={(v) =>
                    field.onChange(v ? "with_return" : "without_return")
                  }
                />
              )}
            />
          )}

          {/* Customs Clearing */}
          {includesCustoms ? (
            <Box
              px={16}
              py={14}
              style={{
                borderRadius: 14,
                border: "1.5px solid #CDEBDD",
                background: "#F6FBF8",
              }}
            >
              <Group gap={13} align="flex-start" wrap="nowrap">
                <Box
                  style={{
                    width: 38,
                    height: 38,
                    flexShrink: 0,
                    borderRadius: 11,
                    display: "flex",
                    alignItems: "center",
                    justifyContent: "center",
                    background: "#ECF6F1",
                    color: "#0A6F4D",
                  }}
                >
                  <FileText size={18} />
                </Box>
                <Box>
                  <Text fz={14} fw={700} c="#10202F">
                    Customs Clearing Service
                  </Text>
                  <Text fz={12} c="#6B7C8E" style={{ lineHeight: 1.4 }}>
                    Customs documentation and clearance is included automatically with this service.
                  </Text>
                </Box>
                <Box style={{ flexShrink: 0, marginLeft: "auto" }}>
                  <Group gap={6} align="center">
                    <Info size={14} color="#0A6F4D" />
                    <Text fz={12} fw={600} c="#0A6F4D">Included</Text>
                  </Group>
                </Box>
              </Group>
            </Box>
          ) : (
            <Controller
              name="customsClearingAgent"
              control={form.control}
              render={({ field, fieldState }) => (
                <Box
                  px={16}
                  py={14}
                  style={{
                    borderRadius: 14,
                    border: "1.5px solid #E6ECF2",
                    background: "#fff",
                  }}
                >
                  <Group gap={13} align="flex-start" wrap="nowrap" mb="sm">
                    <Box
                      style={{
                        width: 38,
                        height: 38,
                        flexShrink: 0,
                        borderRadius: 11,
                        display: "flex",
                        alignItems: "center",
                        justifyContent: "center",
                        background: "#F1F4F7",
                        color: "#64748B",
                      }}
                    >
                      <FileText size={18} />
                    </Box>
                    <Box>
                      <Text fz={14} fw={700} c="#10202F">
                        Customs Clearing Agent
                      </Text>
                      <Text fz={12} c="#6B7C8E" style={{ lineHeight: 1.4 }}>
                        Enter the name of the customs clearing agent for this shipment.
                      </Text>
                    </Box>
                  </Group>
                  <TextInput
                    {...field}
                    placeholder="Customs clearing agent name"
                    error={fieldState.error?.message}
                    radius={10}
                    styles={fieldStyles}
                  />
                </Box>
              )}
            />
          )}
        </Stack>
      )}
    </StepCard>
  );
}

/**
 * Compact service-type selection card. A single horizontal row (icon · text ·
 * radio) — deliberately smaller than the shared OptionCard so the service list
 * stays scannable.
 */
function ServiceTypeCard({
  selected,
  onClick,
  title,
  description,
}: {
  selected: boolean;
  onClick: () => void;
  title?: ReactNode;
  description?: ReactNode;
}) {
  return (
    <button
      type="button"
      onClick={onClick}
      style={{
        width: "100%",
        textAlign: "left",
        cursor: "pointer",
        borderRadius: 12,
        padding: "12px 14px",
        transition: "all 140ms ease",
        border: `1.5px solid ${selected ? "#12B981" : "#E6ECF2"}`,
        background: selected ? "#F4FBF7" : "#fff",
        boxShadow: selected
          ? "0 0 0 1px #12B981, 0 4px 12px rgba(14,163,113,0.10)"
          : "0 1px 2px rgba(16,24,40,0.04)",
      }}
      onMouseEnter={(e) => {
        if (!selected) e.currentTarget.style.borderColor = "#BFE3D2";
      }}
      onMouseLeave={(e) => {
        if (!selected) e.currentTarget.style.borderColor = "#E6ECF2";
      }}
    >
      <Group gap={11} align="center" wrap="nowrap">
        <Box
          style={{
            width: 34,
            height: 34,
            flexShrink: 0,
            borderRadius: 9,
            display: "flex",
            alignItems: "center",
            justifyContent: "center",
            background: selected ? "#E3F4EC" : "#EEF0FB",
            color: selected ? "#0A6F4D" : "#4F46E5",
          }}
        >
          <Train size={17} />
        </Box>
        <Box style={{ minWidth: 0, flex: 1 }}>
          <Text fz={13.5} fw={700} c="#10202F" truncate>
            {title}
          </Text>
          {description && (
            <Text fz={11.5} c="#6B7C8E" truncate style={{ lineHeight: 1.35 }}>
              {description}
            </Text>
          )}
        </Box>
        <Box
          style={{
            width: 18,
            height: 18,
            flexShrink: 0,
            borderRadius: "50%",
            display: "flex",
            alignItems: "center",
            justifyContent: "center",
            border: selected ? "none" : "1.5px solid #CBD5E1",
            background: selected ? "#12B981" : "transparent",
          }}
        >
          {selected && <Check size={11} color="#fff" strokeWidth={3} />}
        </Box>
      </Group>
    </button>
  );
}

function ServiceToggle({
  icon,
  title,
  description,
  checked,
  onChange,
  children,
}: {
  icon: ReactNode;
  title: string;
  description: string;
  checked: boolean;
  onChange: (v: boolean) => void;
  children?: ReactNode;
}) {
  return (
    <Box
      px={16}
      py={14}
      style={{
        borderRadius: 14,
        border: `1.5px solid ${checked ? "#CDEBDD" : "#E6ECF2"}`,
        background: checked ? "#F6FBF8" : "#fff",
        transition: "all 150ms ease",
      }}
    >
      <Group justify="space-between" align="flex-start" wrap="nowrap" gap={12}>
        <Group gap={13} align="flex-start" wrap="nowrap">
          <Box
            style={{
              width: 38,
              height: 38,
              flexShrink: 0,
              borderRadius: 11,
              display: "flex",
              alignItems: "center",
              justifyContent: "center",
              background: checked ? "#ECF6F1" : "#F1F4F7",
              color: checked ? "#0A6F4D" : "#64748B",
            }}
          >
            {icon}
          </Box>
          <Box>
            <Text fz={14} fw={700} c="#10202F">
              {title}
            </Text>
            <Text fz={12} c="#6B7C8E" style={{ lineHeight: 1.4 }}>
              {description}
            </Text>
          </Box>
        </Group>
        <Switch
          checked={checked}
          onChange={(e) => onChange(e.currentTarget.checked)}
          color="edr-green"
          size="md"
          style={{ flexShrink: 0 }}
        />
      </Group>
      {children}
    </Box>
  );
}
