import { Alert, Button, Group, Modal, Select, Stack, Text } from "@mantine/core";
import { useMutation, useQuery } from "@tanstack/react-query";
import { isAxiosError } from "axios";
import { MapPin } from "lucide-react";
import { useEffect, useState } from "react";

import { api } from "@/services/api";
import type { TrainComposition } from "@/services/trainBuilder.service";
import { useToast } from "@/hooks/use-toast";

const parseError = (error: unknown, fallback: string) => {
  if (isAxiosError(error)) {
    const message = error.response?.data?.message;
    if (Array.isArray(message)) return message.join(", ");
    if (typeof message === "string") return message;
  }
  return fallback;
};

/**
 * Relocate the train to another yard. The consist moves as one unit — every
 * coupled locomotive and wagon follows, so their current yards always match
 * the train's.
 */
export default function ChangeYardModal({ composition, opened, onClose }: ChangeYardModalProps) {
  const { toast } = useToast();
  const [yardId, setYardId] = useState("");

  const yardsQuery = useQuery(api.routes.yards.queryOptions({ staleTime: 5 * 60_000 }));
  const setYard = useMutation(api.trainBuilder.setYard.mutationOptions());

  useEffect(() => {
    if (opened) setYardId(composition?.currentYard?.id ?? "");
  }, [opened, composition]);

  const handleSave = async () => {
    if (!composition || !yardId) return;
    try {
      await setYard.mutateAsync({ id: composition.id, currentYardId: yardId });
      toast({ title: "Train relocated" });
      onClose();
    } catch (err) {
      toast({
        title: "Relocation failed",
        description: parseError(err, "Could not change the yard"),
        variant: "destructive",
      });
    }
  };

  const memberCount =
    (composition?.locomotives.length ?? 0) + (composition?.totals.wagonCount ?? 0);

  return (
    <Modal
      opened={opened}
      onClose={onClose}
      title={<Text fw={600}>Change yard — train {composition?.code}</Text>}
      radius="lg"
      centered
    >
      <Stack gap="md">
        <Alert color="yellow" icon={<MapPin size={16} />}>
          The whole consist moves with the train: {composition?.locomotives.length ?? 0}{" "}
          locomotive{(composition?.locomotives.length ?? 0) === 1 ? "" : "s"} and{" "}
          {composition?.totals.wagonCount ?? 0} wagon
          {(composition?.totals.wagonCount ?? 0) === 1 ? "" : "s"} ({memberCount} vehicles)
          are relocated so their current yard always matches the train's. Wagon moves are
          recorded in the movement ledger.
        </Alert>
        <Select
          label="New yard"
          placeholder="Select yard"
          data={(yardsQuery.data ?? []).map((y) => ({
            value: y.id,
            label: y.label ?? y.code,
          }))}
          value={yardId || null}
          onChange={(v) => setYardId(v ?? "")}
          searchable
        />
        <Group justify="flex-end">
          <Button variant="default" onClick={onClose}>
            Cancel
          </Button>
          <Button
            loading={setYard.isPending}
            disabled={!yardId || yardId === composition?.currentYard?.id}
            onClick={handleSave}
          >
            Relocate train
          </Button>
        </Group>
      </Stack>
    </Modal>
  );
}

export interface ChangeYardModalProps {
  composition: TrainComposition | null;
  opened: boolean;
  onClose: () => void;
}
