import type { ColumnDef } from "@edr/ui-common";
import { Box, Button, Card, Container, Group, Modal, Select, Stack, Text, Title } from "@mantine/core";
import { useMutation, useQuery } from "@tanstack/react-query";

import { api } from "@/services/api";
import Breadcrumbs from "@/components/ui/Breadcrumbs";
import { Plus } from "lucide-react";
import { useEffect, useMemo, useState } from "react";
import { Navigate, useLocation } from "react-router-dom";

import FleetCardGrid from "@/components/fleet/FleetCardGrid";
import FleetFormDialog from "@/components/fleet/FleetFormDialog";
import FleetRecordActions from "@/components/fleet/FleetRecordActions";
import FleetToolbar from "@/components/fleet/FleetToolbar";
import { formatFleetCell, registerFleetOptionLabels } from "@/components/fleet/fleetFormat";
import { useFleetViewMode } from "@/components/fleet/useFleetViewMode";
import { ruleEngineTable } from "@/components/ruleEngine/ruleEngineStyles";
import { useToast } from "@/hooks/use-toast";
import {
    FLEET_SELECT_NONE,
    getFleetResource,
    getFleetSlugFromPath,
    type FleetFormFieldDef,
    type FleetResourceSlug,
} from "@/pages/fleet/config/resources";
import type { FleetListFilters, FleetRecord } from "@/services/fleet/fleet.service";
import { DataTable, DataTableFooter, usePagination } from "@edr/ui-common";

const DEFAULT_SLUG: FleetResourceSlug = "locomotives";

const FleetResourcePage = () => {
  const location = useLocation();
  const slug = getFleetSlugFromPath(location.pathname) ?? DEFAULT_SLUG;
  const config = getFleetResource(slug);
  const { toast } = useToast();

  const { pagination, setPagination } = usePagination({ pageSize: 10 });
  const [search, setSearch] = useState("");
  const [statusFilter, setStatusFilter] = useState("ALL");
  const [listFilterValues, setListFilterValues] = useState<Record<string, string>>({});
  const [formOpen, setFormOpen] = useState(false);
  const [editing, setEditing] = useState<FleetRecord | null>(null);
  const [removeTarget, setRemoveTarget] = useState<FleetRecord | null>(null);
  const [assigningDriver, setAssigningDriver] = useState<FleetRecord | null>(null);
  const [selectedDriver, setSelectedDriver] = useState<string>("");
  const { viewMode, setViewMode } = useFleetViewMode(slug);

  const serverListFilters = useMemo((): FleetListFilters | undefined => {
    if (slug !== "wagons" && slug !== "locomotives") return undefined;
    const filters: FleetListFilters = {};
    const status = listFilterValues.status;
    const currentYardId = listFilterValues.currentYardId;
    if (status && status !== "ALL") {
      (filters as { status?: string }).status = status;
    }
    if (currentYardId && currentYardId !== "ALL") {
      filters.currentYardId = currentYardId;
    }
    if (slug === "wagons" && search.trim()) {
      filters.search = search.trim();
    }
    return filters;
  }, [slug, listFilterValues, search]);

  const { data: allRows = [], isLoading, isError, error } = useQuery(
    api.fleet.list.queryOptions({ input: { slug, filters: serverListFilters } }),
  );
  const create = useMutation(api.fleet.create.mutationOptions());
  const update = useMutation(api.fleet.update.mutationOptions());
  const remove = useMutation(api.fleet.remove.mutationOptions());

  const { data: wagonTypes = [], isLoading: wagonTypesLoading } = useQuery(
    api.wagonTypes.list.queryOptions(),
  );
  const { data: containerTypes = [], isLoading: containerTypesLoading } = useQuery(
    api.containerTypes.list.queryOptions({ staleTime: Infinity }),
  );
  const { data: cargoTypes = [], isLoading: cargoTypesLoading } = useQuery(
    api.cargoTypes.list.queryOptions({ staleTime: Infinity }),
  );
  const { data: wagons = [], isLoading: wagonsLoading } = useQuery(
    api.wagons.list.queryOptions({ input: {} }),
  );
  const { data: containers = [], isLoading: containersLoading } = useQuery(
    api.containers.list.queryOptions(),
  );
  const { data: yards = [], isLoading: yardsLoading } = useQuery(
    api.routes.yards.queryOptions(),
  );
  const { data: drivers = [] } = useQuery(
    api.fleet.list.queryOptions({ input: { slug: "drivers" } }),
  );

  useEffect(() => {
    setPagination((prev) => ({ pageIndex: 0, pageSize: prev.pageSize }));
    setSearch("");
    setStatusFilter("ALL");
    setListFilterValues({});
  }, [slug, setPagination]);

  useEffect(() => {
    setPagination((prev) => ({ pageIndex: 0, pageSize: prev.pageSize }));
  }, [search, listFilterValues, setPagination]);

  const hasStatusColumn = Boolean(config?.columns.some((col) => col.accessorKey === "status"));
  const usesServerListFilters = Boolean(config?.listFilters?.length);

  const statusFilterOptions = useMemo(() => {
    if (!hasStatusColumn || usesServerListFilters) return [];
    if (slug === "vehicles" || slug === "drivers") {
      return [
        { value: "ALL", label: "All statuses" },
        { value: "ACTIVE", label: "Active" },
        { value: "INACTIVE", label: "Inactive" },
      ];
    }
    const statuses = new Set(
      allRows
        .map((row) => String((row as unknown as Record<string, unknown>).status ?? ""))
        .filter(Boolean),
    );
    return [
      { value: "ALL", label: "All statuses" },
      ...[...statuses].sort().map((status) => ({ value: status, label: status })),
    ];
  }, [allRows, hasStatusColumn, usesServerListFilters, slug]);

  const dynamicOptions = useMemo(() => {
    const wagonTypeOpts = (wagonTypes as Array<{ id: string; code: string; name?: string }>).map(
      (t) => ({ value: t.id, label: `${t.code}${t.name ? ` - ${t.name}` : ""}` }),
    );
    const containerTypeOpts = (
      containerTypes as Array<{ id: string; label?: string; code?: string }>
    ).map((t) => ({ value: t.id, label: t.label ?? t.code ?? t.id }));
    const cargoTypeOpts = (
      cargoTypes as Array<{ id: string; cargoTypeName?: string; code?: string }>
    ).map((t) => ({ value: t.id, label: t.cargoTypeName ?? t.code ?? t.id }));
    const wagonOpts = (wagons as Array<{ id: string; wagonNumber: string }>).map((w) => ({
      value: w.id,
      label: w.wagonNumber,
    }));
    const containerOpts = (containers as Array<{ id: string; containerNumber: string }>).map(
      (c) => ({ value: c.id, label: c.containerNumber }),
    );

    const yardOpts = (yards as Array<{ id: string; label?: string; code?: string }>).map(
      (y) => ({ value: y.id, label: y.label ?? y.code ?? y.id }),
    );

    registerFleetOptionLabels("currentYardId", yardOpts);

    return {
      wagonTypes: wagonTypeOpts,
      containerTypes: containerTypeOpts,
      cargoTypes: [{ label: "None", value: FLEET_SELECT_NONE }, ...cargoTypeOpts],
      wagons: [{ label: "Unassigned", value: FLEET_SELECT_NONE }, ...wagonOpts],
      containers: containerOpts,
      yards: yardOpts,
    };
  }, [wagonTypes, containerTypes, cargoTypes, wagons, containers, yards]);

  const listFilterSelects = useMemo(() => {
    if (!config?.listFilters?.length) return null;
    return config.listFilters.map((filter) => {
      const dynamicOpts = filter.dynamicOptions
        ? (dynamicOptions[filter.dynamicOptions] ?? [])
        : [];
      const staticOpts =
        filter.options?.map((opt) => ({ value: opt.value, label: opt.label })) ?? [];
      const opts = filter.dynamicOptions ? dynamicOpts : staticOpts;
      return {
        ...filter,
        value: listFilterValues[filter.key] ?? "ALL",
        data: [
          { value: "ALL", label: filter.allLabel ?? `All ${filter.label.toLowerCase()}` },
          ...opts,
        ],
      };
    });
  }, [config?.listFilters, listFilterValues, dynamicOptions]);

  useEffect(() => {
    registerFleetOptionLabels("wagonTypeId", dynamicOptions.wagonTypes);
    registerFleetOptionLabels("containerTypeId", dynamicOptions.containerTypes);
    registerFleetOptionLabels(
      "cargoTypeId",
      dynamicOptions.cargoTypes.filter((o) => o.value !== FLEET_SELECT_NONE),
    );
    registerFleetOptionLabels("wagonId", dynamicOptions.wagons);
    registerFleetOptionLabels("containerId", dynamicOptions.containers);
    registerFleetOptionLabels("currentYardId", dynamicOptions.yards);
  }, [dynamicOptions]);

  const formFields = useMemo((): FleetFormFieldDef[] => {
    if (!config) return [];
    return config.formFields.map((field) => {
      if (!field.dynamicOptions) return field;
      const options = dynamicOptions[field.dynamicOptions] ?? [];
      return { ...field, type: "select" as const, options };
    });
  }, [config, dynamicOptions]);

  const selectOptionsLoading =
    wagonTypesLoading ||
    containerTypesLoading ||
    cargoTypesLoading ||
    wagonsLoading ||
    containersLoading ||
    yardsLoading;

  const filteredRows = useMemo(() => {
    if (!config) return allRows;
    if (usesServerListFilters) return allRows;
    const term = search.trim().toLowerCase();
    return allRows.filter((row) => {
      const record = row as unknown as Record<string, unknown>;
      if (statusFilter !== "ALL" && String(record.status ?? "") !== statusFilter) {
        return false;
      }
      if (!term) return true;
      return config.searchKeys.some((key) =>
        String(record[key] ?? "")
          .toLowerCase()
          .includes(term),
      );
    });
  }, [allRows, search, statusFilter, config, usesServerListFilters]);

  const pageCount = Math.max(1, Math.ceil(filteredRows.length / pagination.pageSize));
  const pagedRows = useMemo(() => {
    const start = pagination.pageIndex * pagination.pageSize;
    return filteredRows.slice(start, start + pagination.pageSize);
  }, [filteredRows, pagination.pageIndex, pagination.pageSize]);

  const columns = useMemo((): ColumnDef<FleetRecord>[] => {
    if (!config) return [];
    const headerClassName = ruleEngineTable.headerCell;
    const cellClassName = ruleEngineTable.bodyCell;

    const base: ColumnDef<FleetRecord>[] = config.columns.map((col) => ({
      id: col.id,
      accessorKey: col.accessorKey,
      header: col.header,
      size: col.size || 150,
      minSize: col.size ? Math.max(col.size - 20, 80) : 80,
      meta: { headerClassName, cellClassName },
      cell: ({ row }) => {
        const value = (row.original as unknown as Record<string, unknown>)[col.accessorKey];
        console.log(`${col.accessorKey}:`, value, 'format:', col.format);
        return formatFleetCell(value, col.format, col.accessorKey);
      },
    }));

    base.push({
      id: "actions",
      header: "Actions",
      size: 160,
      meta: { headerClassName, cellClassName: `${cellClassName} whitespace-nowrap` },
      cell: ({ row }) => (
        <div onClick={(e) => e.stopPropagation()} data-stop-row-click>
          <FleetRecordActions
            record={row.original}
            config={config}
            layout="compact"
            onEdit={(record) => {
              setEditing(record);
              setFormOpen(true);
            }}
            onRemove={setRemoveTarget}
            onAssignDriver={setAssigningDriver}
          />
        </div>
      ),
    });

    return base;
  }, [config, dynamicOptions.yards]);

  const tableStatus = isLoading ? "loading" : isError ? "error" : "success";

  if (!config) {
    return <Navigate to="/dashboard/locomotives" replace />;
  }

  const handleFormSubmit = async (values: Record<string, unknown>) => {
    try {
      if (editing && "id" in editing) {
        await update.mutateAsync({ slug, id: String(editing.id), data: values });
        toast({ title: `${config.entityLabel} updated` });
      } else {
        await create.mutateAsync({ slug, data: values });
        toast({ title: `${config.entityLabel} created` });
      }
      setFormOpen(false);
      setEditing(null);
    } catch (err: unknown) {
      const message =
        (err as { response?: { data?: { message?: string } } })?.response?.data?.message ??
        "Save failed";
      toast({ title: "Save failed", description: String(message), variant: "destructive" });
    }
  };

  const handleRemove = async () => {
    if (!removeTarget || !("id" in removeTarget)) return;
    try {
      await remove.mutateAsync({ slug, id: String(removeTarget.id) });
      toast({
        title: config.removeSuccessMessage ?? `${config.entityLabel} removed`,
      });
      setRemoveTarget(null);
    } catch (err: unknown) {
      const message =
        (err as { response?: { data?: { message?: string } } })?.response?.data?.message ??
        "Remove failed";
      toast({ title: "Remove failed", description: String(message), variant: "destructive" });
    }
  };

  const handleAssignDriver = async () => {
    if (!assigningDriver || !("id" in assigningDriver) || !selectedDriver) return;
    try {
      const selectedDriverRecord = (drivers as unknown as Array<Record<string, unknown>>).find(
        (d) => String(d.id) === selectedDriver
      );
      if (!selectedDriverRecord) return;

      const driverName = `${selectedDriverRecord.firstName} ${selectedDriverRecord.lastName}`;

      await update.mutateAsync({
        slug,
        id: String(assigningDriver.id),
        data: {
          assignedDriverId: selectedDriver,
          assignedDriverName: driverName,
        },
      });
      toast({ title: "Driver assigned successfully" });
      setAssigningDriver(null);
      setSelectedDriver("");
    } catch (err: unknown) {
      const message =
        (err as { response?: { data?: { message?: string } } })?.response?.data?.message ??
        "Assignment failed";
      toast({ title: "Assignment failed", description: String(message), variant: "destructive" });
    }
  };

  const itemLabel = config.label.toLowerCase();

  return (
    <Container size="xxl" py="lg">
      <Breadcrumbs items={[{ label: config.label }]} />

      <Stack gap="lg" mt="sm">
        <Group justify="space-between" align="flex-end">
          <div>
            <Title order={2}>{config.label}</Title>
            <Text c="dimmed" size="sm">
              {config.subtitle}
            </Text>
          </div>
          <Button leftSection={<Plus size={16} />} styles={{ label: { fontWeight: 500 } }} onClick={() => {
            setEditing(null);
            setFormOpen(true);
          }}>
            {config.addLabel}
          </Button>
        </Group>

      <Card radius="lg" padding={0} withBorder style={{ borderColor: "var(--mantine-color-gray-2)" }}>
        <Stack gap={0}>
          <Box px="md" pt="md" pb="md" w="100%" style={{ borderBottom: "1px solid var(--mantine-color-gray-2)" }}>
            <FleetToolbar
              search={search}
              onSearchChange={setSearch}
              searchPlaceholder={config.searchPlaceholder}
              showSearch={config.supportsSearch}
              viewMode={viewMode}
              onViewModeChange={setViewMode}
              filters={
                listFilterSelects ? (
                  <Group gap="xs" wrap="wrap">
                    {listFilterSelects.map((filter) => (
                      <Group key={filter.key} gap={4} wrap="wrap">
                        <Text size="xs" fw={500} c="dimmed">{filter.label}:</Text>
                        <Group gap={4} wrap="wrap">
                          {[{ value: "ALL", label: "All" }, ...filter.data].map((option) => (
                            <Button
                              key={option.value}
                              size="xs"
                              radius="md"
                              variant={filter.value === option.value ? "filled" : "outline"}
                              styles={{ label: { fontWeight: 500 } }}
                              onClick={() => {
                                setListFilterValues((prev) => ({
                                  ...prev,
                                  [filter.key]: option.value,
                                }));
                                setPagination((prev) => ({ ...prev, pageIndex: 0 }));
                              }}
                            >
                              {option.label}
                            </Button>
                          ))}
                        </Group>
                      </Group>
                    ))}
                  </Group>
                ) : hasStatusColumn && statusFilterOptions.length > 1 ? (
                  <Group gap={4} wrap="wrap">
                    <Text size="xs" fw={500} c="dimmed">Status:</Text>
                    <Group gap={4} wrap="wrap">
                      {[{ value: "ALL", label: "All" }, ...statusFilterOptions].map((option) => (
                        <Button
                          key={option.value}
                          size="xs"
                          radius="md"
                          variant={statusFilter === option.value ? "filled" : "outline"}
                          styles={{ label: { fontWeight: 500 } }}
                          onClick={() => setStatusFilter(option.value)}
                        >
                          {option.label}
                        </Button>
                      ))}
                    </Group>
                  </Group>
                ) : undefined
              }
            />
          </Box>

          {viewMode === "table" ? (
            <Box style={{
              overflowX: "auto",
              width: "100%",
              WebkitOverflowScrolling: "touch",
            }}>
              <DataTable
                columns={columns}
                data={pagedRows}
                status={tableStatus}
                error={
                  isError
                    ? {
                        message: "Failed to load data",
                        description: error instanceof Error ? error.message : "Unknown error",
                      }
                    : undefined
                }
                emptyMessage={`No ${itemLabel} found`}
                pagination={{
                  pageIndex: pagination.pageIndex,
                  pageSize: pagination.pageSize,
                  pageCount,
                  totalCount: filteredRows.length,
                }}
                tableOptions={{
                  manualPagination: true,
                  pageCount,
                  state: { pagination },
                  onPaginationChange: setPagination,
                }}
                containerClassName="border-0 shadow-none bg-transparent"
                footer={({ table, pagination: footerPagination }) => (
                  <DataTableFooter
                    table={table}
                    pagination={footerPagination}
                    options={{ labels: { items: itemLabel } }}
                  />
                )}
              />
            </Box>
          ) : (
            <FleetCardGrid
              config={config}
              rows={pagedRows}
              status={tableStatus}
              emptyMessage={`No ${itemLabel} found`}
              pagination={pagination}
              pageCount={pageCount}
              totalCount={filteredRows.length}
              onPaginationChange={setPagination}
              onEdit={(record) => {
                setEditing(record);
                setFormOpen(true);
              }}
              onRemove={setRemoveTarget}
            />
          )}
        </Stack>
      </Card>
      </Stack>

      <FleetFormDialog
        open={formOpen}
        onOpenChange={(open) => {
          setFormOpen(open);
          if (!open) setEditing(null);
        }}
        title={editing ? `Edit ${config.entityLabel}` : config.addLabel}
        fields={formFields}
        initialRecord={editing}
        emptyValues={config.emptyValues}
        isSubmitting={create.isPending || update.isPending}
        selectOptionsLoading={selectOptionsLoading}
        onSubmit={handleFormSubmit}
      />

      <Modal
        opened={Boolean(removeTarget)}
        onClose={() => setRemoveTarget(null)}
        title={<Text fw={600}>{config.removeActionLabel ?? "Delete"}</Text>}
        radius="lg"
        centered
      >
        <Stack gap="md">
          <Text size="sm">
            {config.removeConfirmMessage ??
              `Are you sure you want to ${config.removeAction} this ${config.entityLabel.toLowerCase()}?`}
          </Text>
          <Group justify="flex-end">
            <Button variant="default" onClick={() => setRemoveTarget(null)}>
              Cancel
            </Button>
            <Button color="red" loading={remove.isPending} onClick={handleRemove}>
              {config.removeActionLabel ?? "Delete"}
            </Button>
          </Group>
        </Stack>
      </Modal>

      <Modal
        opened={Boolean(assigningDriver)}
        onClose={() => {
          setAssigningDriver(null);
          setSelectedDriver("");
        }}
        title={<Text fw={600}>Assign Driver</Text>}
        radius="lg"
        centered
      >
        <Stack gap="md">
          <Text size="sm">
            {assigningDriver && "id" in assigningDriver ?
              `Assign a driver to vehicle: ${(assigningDriver as unknown as Record<string, unknown>).plateNumber}`
              : "Select a driver to assign"}
          </Text>
          <Select
            label="Driver"
            placeholder="Select a driver"
            searchable
            clearable
            value={selectedDriver}
            onChange={(value) => setSelectedDriver(value || "")}
            data={(drivers as unknown as Array<Record<string, unknown>>).map((driver) => ({
              value: String(driver.id || ""),
              label: `${driver.firstName} ${driver.lastName} (${driver.licenseNumber})`,
            }))}
          />
          <Group justify="flex-end">
            <Button variant="default" onClick={() => {
              setAssigningDriver(null);
              setSelectedDriver("");
            }}>
              Cancel
            </Button>
            <Button
              onClick={handleAssignDriver}
              disabled={!selectedDriver}
              loading={update.isPending}
            >
              Assign
            </Button>
          </Group>
        </Stack>
      </Modal>
    </Container>
  );
};

export default FleetResourcePage;
