import { useEffect, useMemo, useState } from "react";
import { Loader2, Calendar } from "lucide-react";
import {
  Button,
  Group,
  Modal,
  NumberInput,
  Select,
  MultiSelect,
  SimpleGrid,
  Stack,
  Text,
  Textarea,
  TextInput,
  ActionIcon,
} from "@mantine/core";

import {
  FLEET_SELECT_NONE,
  type FleetFormFieldDef,
} from "@/pages/fleet/config/resources";
import type { FleetRecord } from "@/services/fleet/fleet.service";

export interface FleetFormDialogProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  title: string;
  fields: FleetFormFieldDef[];
  initialRecord?: FleetRecord | null;
  emptyValues: Record<string, unknown>;
  isSubmitting: boolean;
  selectOptionsLoading?: boolean;
  onSubmit: (values: Record<string, unknown>) => void;
}

const buildInitialValues = (
  fields: FleetFormFieldDef[],
  emptyValues: Record<string, unknown>,
  record?: FleetRecord | null,
): Record<string, unknown> => {
  const values: Record<string, unknown> = { ...emptyValues };
  if (!record) return values;

  fields.forEach((field) => {
    const raw = (record as unknown as Record<string, unknown>)[field.name];
    if (raw === null || raw === undefined) {
      values[field.name] = field.noneOption ? FLEET_SELECT_NONE : "";
      return;
    }
    values[field.name] = raw;
  });
  return values;
};

const FleetFormDialog = ({
  open,
  onOpenChange,
  title,
  fields,
  initialRecord,
  emptyValues,
  isSubmitting,
  selectOptionsLoading,
  onSubmit,
}: FleetFormDialogProps) => {
  const [values, setValues] = useState<Record<string, unknown>>({});
  const [errors, setErrors] = useState<Record<string, string>>({});

  useEffect(() => {
    if (open) {
      setValues(buildInitialValues(fields, emptyValues, initialRecord));
      setErrors({});
    }
  }, [open, fields, emptyValues, initialRecord]);

  const shortFields = useMemo(
    () => fields.filter((f) => f.type !== "textarea"),
    [fields],
  );
  const longFields = useMemo(
    () => fields.filter((f) => f.type === "textarea"),
    [fields],
  );

  const validate = () => {
    const next: Record<string, string> = {};
    fields.forEach((field) => {
      const value = values[field.name];
      const stringValue =
        typeof value === "string" ? value.trim() : String(value ?? "");

      if (
        field.required &&
        (stringValue === "" || stringValue === FLEET_SELECT_NONE)
      ) {
        next[field.name] = `${field.label} is required`;
      }

      // Validate date format (YYYY-MM-DD) - DatePicker ensures this
      if (
        field.type === "date" &&
        stringValue &&
        stringValue !== FLEET_SELECT_NONE
      ) {
        const dateRegex = /^\d{4}-\d{2}-\d{2}$/;
        if (!dateRegex.test(stringValue)) {
          next[field.name] = `${field.label} must be a valid date`;
        } else {
          const date = new Date(stringValue + "T00:00:00Z");
          if (isNaN(date.getTime())) {
            next[field.name] = `${field.label} is not a valid date`;
          } else if (date > new Date()) {
            next[field.name] = `${field.label} cannot be in the future`;
          }
        }
      }
    });
    setErrors(next);
    return Object.keys(next).length === 0;
  };

  const handleSubmit = () => {
    if (!validate()) return;
    const payload = Object.fromEntries(
      Object.entries(values)
        .map(([key, value]) => {
          if (value === FLEET_SELECT_NONE || value === "")
            return [key, undefined];
          return [key, value];
        })
        .filter(([, value]) => value !== undefined),
    );
    onSubmit(payload);
  };

  const renderField = (field: FleetFormFieldDef) => {
    const value = values[field.name];
    const error = errors[field.name];

    if (field.type === "select") {
      return (
        <Select
          key={field.name}
          label={field.label}
          data={field.options ?? []}
          value={
            value == null || value === ""
              ? field.noneOption
                ? FLEET_SELECT_NONE
                : null
              : String(value)
          }
          onChange={(next) =>
            setValues((current) => ({ ...current, [field.name]: next ?? "" }))
          }
          error={error}
          searchable
          disabled={selectOptionsLoading}
          rightSection={
            selectOptionsLoading ? (
              <Loader2 size={14} className="animate-spin" />
            ) : undefined
          }
        />
      );
    }

    if (field.type === "multiselect") {
      const arrayValue = Array.isArray(value)
        ? value
        : typeof value === "string" && value
          ? [value]
          : [];

      return (
        <MultiSelect
          key={field.name}
          label={field.label}
          placeholder={field.placeholder || "Select options"}
          data={field.options ?? []}
          value={arrayValue.map(String)}
          onChange={(next) =>
            setValues((current) => ({ ...current, [field.name]: next }))
          }
          error={error}
          searchable
          clearable
          disabled={selectOptionsLoading}
          rightSection={
            selectOptionsLoading ? (
              <Loader2 size={14} className="animate-spin" />
            ) : undefined
          }
        />
      );
    }

    if (field.type === "number") {
      return (
        <NumberInput
          key={field.name}
          label={field.label}
          placeholder={field.placeholder}
          value={value === "" || value == null ? "" : Number(value)}
          onChange={(next) =>
            setValues((current) => ({
              ...current,
              [field.name]: next === "" ? "" : next,
            }))
          }
          error={error}
          disabled={field.disabled}
        />
      );
    }

    if (field.type === "textarea") {
      return (
        <Textarea
          key={field.name}
          label={field.label}
          placeholder={field.placeholder}
          value={String(value ?? "")}
          onChange={(e) =>
            setValues((current) => ({
              ...current,
              [field.name]: e.currentTarget?.value,
            }))
          }
          error={error}
          minRows={3}
          disabled={field.disabled}
        />
      );
    }

    if (field.type === "date") {
      return (
        <TextInput
          key={field.name}
          type="date"
          label={field.label}
          placeholder={field.placeholder || "YYYY-MM-DD"}
          value={typeof value === "string" ? value.slice(0, 10) : ""}
          onChange={(e) =>
            setValues((current) => ({
              ...current,
              [field.name]: e.currentTarget?.value ?? "",
            }))
          }
          error={error}
          disabled={field.disabled}
          description={field.description || "Select a date"}
          rightSection={
            <ActionIcon size="sm" variant="subtle" color="green">
              <Calendar size={16} />
            </ActionIcon>
          }
          size="sm"
          radius="md"
          styles={{
            input: {
              borderColor: "var(--mantine-color-gray-3)",
              backgroundColor: "var(--mantine-color-gray-0)",
              transition: "all 200ms ease",
              "&:focus": {
                borderColor: "var(--mantine-color-green-5)",
                backgroundColor: "var(--mantine-color-gray-1)",
              },
            },
          }}
        />
      );
    }

    return (
      <TextInput
        key={field.name}
        label={field.label}
        placeholder={field.placeholder}
        description={field.description}
        value={String(value ?? "")}
        onChange={(e) =>
          setValues((current) => ({
            ...current,
            [field.name]: e.currentTarget?.value,
          }))
        }
        error={error}
        disabled={field.disabled}
      />
    );
  };

  return (
    <Modal
      opened={open}
      onClose={() => onOpenChange(false)}
      title={<Text fw={600}>{title}</Text>}
      size="lg"
      radius="lg"
      centered
    >
      <Stack gap="md">
        <SimpleGrid cols={{ base: 1, sm: 2 }} spacing="md">
          {shortFields.map(renderField)}
        </SimpleGrid>
        {longFields.map(renderField)}
        <Group justify="flex-end" gap="sm" mt="sm">
          <Button variant="default" onClick={() => onOpenChange(false)}>
            Cancel
          </Button>
          <Button
            color="edr-green"
            loading={isSubmitting}
            onClick={handleSubmit}
          >
            Save
          </Button>
        </Group>
      </Stack>
    </Modal>
  );
};

export default FleetFormDialog;
