"use client";

import { useState } from "react";

import { CheckCircle } from "lucide-react";

import { Drawer } from "@/components/ui/Drawer";
import {
  useSubmitPilotRequest,
  type PilotRequestPayload,
} from "@/lib/api/landing";

// ── Types ──────────────────────────────────────────────────────────────────

interface Props {
  open: boolean;
  onClose: () => void;
}

interface FormState {
  name: string;
  phone: string;
  email: string;
  company: string;
  message: string;
}

type FieldName = keyof FormState;
type FieldErrors = Partial<Record<FieldName, string>>;

// ── Schema mirror ──────────────────────────────────────────────────────────
// Зеркалирует backend Pydantic-схему `PilotRequestInput`
// (`backend/app/api/v1/pilot.py:25-34`). При изменении на бэкенде —
// синхронизировать здесь, иначе лид получит 422 и сырой JSON в модалке.
export const PILOT_LIMITS = {
  name: { min: 2, max: 200 },
  phone: { max: 50 },
  email: { max: 200 },
  company: { max: 200 },
  message: { max: 2000 },
} as const;

// Тот же паттерн, что и в Pydantic Field(pattern=...) на бэкенде
// (`backend/app/api/v1/pilot.py:31`).
export const PILOT_EMAIL_RE = /^[^@\s]+@[^@\s]+\.[^@\s]+$/;

// ── Helpers ────────────────────────────────────────────────────────────────

/** Derives a human-readable tracking ID from the UUID string returned by backend.
 *
 * Важно: показанный лиду номер ДОЛЖЕН находиться поддержкой в БД. Бэкенд
 * (`backend/app/api/v1/pilot.py`) хранит и логирует полный uuid `id`, поэтому
 * мы берём его реальный 8-символьный префикс БЕЗ изменения регистра — он остаётся
 * буквальным префиксом `pilot_requests.id`. Поддержка находит заявку прямым
 * запросом: `SELECT * FROM pilot_requests WHERE id::text LIKE 'XXXXXXXX%'`.
 * Префикс "GD-" — только визуальный, в запрос НЕ входит.
 * Example: "7f3a8c2e-..." → "GD-7f3a8c2e"
 */
function deriveTrackingId(id: string): string {
  return "GD-" + id.replace(/-/g, "").slice(0, 8);
}

/**
 * Валидирует одно поле против ограничений схемы. Возвращает текст ошибки
 * (понятный пользователю) или пустую строку, если поле валидно.
 *
 * Экспортится для unit-тестов и потенциального переиспользования.
 */
export function validatePilotField(name: FieldName, value: string): string {
  const trimmed = value.trim();
  switch (name) {
    case "name":
      if (!trimmed) return "Укажите имя";
      if (trimmed.length < PILOT_LIMITS.name.min)
        return `Минимум ${PILOT_LIMITS.name.min} символа`;
      if (trimmed.length > PILOT_LIMITS.name.max)
        return `Максимум ${PILOT_LIMITS.name.max} символов`;
      return "";
    case "phone":
      if (trimmed.length > PILOT_LIMITS.phone.max)
        return `Максимум ${PILOT_LIMITS.phone.max} символов`;
      return "";
    case "email":
      if (!trimmed) return "";
      if (trimmed.length > PILOT_LIMITS.email.max)
        return `Максимум ${PILOT_LIMITS.email.max} символов`;
      if (!PILOT_EMAIL_RE.test(trimmed)) return "Некорректный email";
      return "";
    case "company":
      if (trimmed.length > PILOT_LIMITS.company.max)
        return `Максимум ${PILOT_LIMITS.company.max} символов`;
      return "";
    case "message":
      if (trimmed.length > PILOT_LIMITS.message.max)
        return `Максимум ${PILOT_LIMITS.message.max} символов`;
      return "";
    default:
      return "";
  }
}

/** Валидирует все поля разом. Пустой объект — форма валидна. */
export function validatePilotForm(form: FormState): FieldErrors {
  const errors: FieldErrors = {};
  (Object.keys(form) as FieldName[]).forEach((key) => {
    const err = validatePilotField(key, form[key]);
    if (err) errors[key] = err;
  });
  return errors;
}

/**
 * Дружелюбное сообщение об ошибке отправки.
 * apiFetch (`lib/api.ts:39`) кладёт сырой response.text() в Error.message
 * как «API error 422: {"detail":[...]}». На публичной лид-форме сырой JSON
 * показывать нельзя — поэтому мапим коды в человеческий текст. На 422 это
 * fallback при рассинхроне фронт/бэк валидации; клиент-сайд должен ловить
 * это до отправки.
 */
export function formatSubmitError(err: unknown): string {
  const fallback = "Не удалось отправить заявку. Попробуйте позже.";
  if (!(err instanceof Error)) return fallback;
  const match = err.message.match(/^API error (\d{3}):\s*(.*)$/s);
  if (!match) return fallback;
  const status = Number(match[1]);
  const body = match[2];
  if (status === 422) {
    return "Проверьте корректность заполнения полей.";
  }
  if (status >= 500) {
    return "Сервер недоступен. Попробуйте позже.";
  }
  try {
    const parsed = JSON.parse(body) as { detail?: unknown };
    if (typeof parsed.detail === "string") return parsed.detail;
  } catch {
    // not JSON — fall through to fallback
  }
  return fallback;
}

// ── Component ──────────────────────────────────────────────────────────────

export function PilotRequestModal({ open, onClose }: Props) {
  const [form, setForm] = useState<FormState>({
    name: "",
    phone: "",
    email: "",
    company: "",
    message: "",
  });
  const [errors, setErrors] = useState<FieldErrors>({});
  const [trackingId, setTrackingId] = useState<string | null>(null);

  const mutation = useSubmitPilotRequest();

  function handleChange(
    e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>,
  ) {
    const { name, value } = e.target;
    const fieldName = name as FieldName;
    setForm((prev) => ({ ...prev, [fieldName]: value }));
    // Live re-validate только для полей где ошибка уже показана (клиент сразу
    // видит, что фикс «помог»), плюс email — исторически на онлайн-проверке.
    setErrors((prev) => {
      if (fieldName !== "email" && !prev[fieldName]) return prev;
      const err = validatePilotField(fieldName, value);
      const next: FieldErrors = { ...prev };
      if (err) next[fieldName] = err;
      else delete next[fieldName];
      return next;
    });
  }

  function handleBlur(
    e: React.FocusEvent<HTMLInputElement | HTMLTextAreaElement>,
  ) {
    const { name, value } = e.target;
    const fieldName = name as FieldName;
    const err = validatePilotField(fieldName, value);
    setErrors((prev) => {
      const next: FieldErrors = { ...prev };
      if (err) next[fieldName] = err;
      else delete next[fieldName];
      return next;
    });
  }

  function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
    e.preventDefault();
    const validation = validatePilotForm(form);
    if (Object.keys(validation).length > 0) {
      setErrors(validation);
      return;
    }

    const payload: PilotRequestPayload = {
      name: form.name.trim(),
      source: "landing",
      ...(form.phone.trim() ? { phone: form.phone.trim() } : {}),
      ...(form.email.trim() ? { email: form.email.trim() } : {}),
      ...(form.company.trim() ? { company: form.company.trim() } : {}),
      ...(form.message.trim()
        ? { message: form.message.trim().slice(0, PILOT_LIMITS.message.max) }
        : {}),
    };

    mutation.mutate(payload, {
      onSuccess: (data) => {
        setTrackingId(deriveTrackingId(data.id));
      },
    });
  }

  function handleClose() {
    setForm({ name: "", phone: "", email: "", company: "", message: "" });
    setErrors({});
    setTrackingId(null);
    mutation.reset();
    onClose();
  }

  const hasBlockingErrors = Object.keys(validatePilotForm(form)).length > 0;
  const submitDisabled = mutation.isPending || hasBlockingErrors;

  return (
    <Drawer open={open} onClose={handleClose} side="bottom">
      {/* Header */}
      <div
        style={{
          display: "flex",
          alignItems: "center",
          justifyContent: "space-between",
          padding: "20px 24px 0",
          marginBottom: 20,
        }}
      >
        <h2
          style={{
            margin: 0,
            fontSize: 18,
            fontWeight: 600,
            color: "var(--fg-primary)",
          }}
        >
          Запросить пилотный доступ
        </h2>
      </div>

      <div style={{ padding: "0 24px 32px" }}>
        {/* Success state */}
        {trackingId !== null ? (
          <div
            style={{
              display: "flex",
              flexDirection: "column",
              alignItems: "flex-start",
              gap: 12,
              padding: "24px 0",
            }}
          >
            <CheckCircle size={40} color="var(--success)" strokeWidth={1.5} />
            <p
              style={{
                margin: 0,
                fontSize: 16,
                fontWeight: 600,
                color: "var(--fg-primary)",
              }}
            >
              Заявка принята
            </p>
            <p
              style={{
                margin: 0,
                fontSize: 14,
                color: "var(--fg-secondary)",
                lineHeight: 1.5,
              }}
            >
              Мы свяжемся с вами в течение 1–2 рабочих дней. Номер заявки:{" "}
              <span
                style={{
                  fontVariantNumeric: "tabular-nums",
                  color: "var(--fg-primary)",
                }}
              >
                {trackingId}
              </span>
            </p>
            <button
              onClick={handleClose}
              style={{
                marginTop: 8,
                padding: "8px 20px",
                background: "var(--accent)",
                color: "#fff",
                border: "none",
                borderRadius: 8,
                fontSize: 14,
                fontWeight: 500,
                cursor: "pointer",
              }}
            >
              Закрыть
            </button>
          </div>
        ) : (
          /* Form */
          <form onSubmit={handleSubmit} noValidate>
            <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
              {/* Name */}
              <div>
                <label htmlFor="pilot-name" style={labelStyle}>
                  Имя *
                </label>
                <input
                  id="pilot-name"
                  name="name"
                  value={form.name}
                  onChange={handleChange}
                  onBlur={handleBlur}
                  required
                  minLength={PILOT_LIMITS.name.min}
                  maxLength={PILOT_LIMITS.name.max}
                  placeholder="Алексей Кириллов"
                  aria-invalid={errors.name ? "true" : "false"}
                  aria-describedby={errors.name ? "pilot-name-error" : undefined}
                  style={{
                    ...inputStyle,
                    borderColor: errors.name
                      ? "var(--danger)"
                      : "var(--border-strong)",
                  }}
                />
                {errors.name ? (
                  <span id="pilot-name-error" style={fieldErrorStyle}>
                    {errors.name}
                  </span>
                ) : null}
              </div>

              {/* Company */}
              <div>
                <label htmlFor="pilot-company" style={labelStyle}>
                  Компания
                </label>
                <input
                  id="pilot-company"
                  name="company"
                  value={form.company}
                  onChange={handleChange}
                  onBlur={handleBlur}
                  maxLength={PILOT_LIMITS.company.max}
                  placeholder="PRINZIP"
                  aria-invalid={errors.company ? "true" : "false"}
                  aria-describedby={
                    errors.company ? "pilot-company-error" : undefined
                  }
                  style={{
                    ...inputStyle,
                    borderColor: errors.company
                      ? "var(--danger)"
                      : "var(--border-strong)",
                  }}
                />
                {errors.company ? (
                  <span id="pilot-company-error" style={fieldErrorStyle}>
                    {errors.company}
                  </span>
                ) : null}
              </div>

              {/* Phone */}
              <div>
                <label htmlFor="pilot-phone" style={labelStyle}>
                  Телефон
                </label>
                <input
                  id="pilot-phone"
                  name="phone"
                  type="tel"
                  value={form.phone}
                  onChange={handleChange}
                  onBlur={handleBlur}
                  maxLength={PILOT_LIMITS.phone.max}
                  placeholder="+7 900 000-00-00"
                  aria-invalid={errors.phone ? "true" : "false"}
                  aria-describedby={
                    errors.phone ? "pilot-phone-error" : undefined
                  }
                  style={{
                    ...inputStyle,
                    borderColor: errors.phone
                      ? "var(--danger)"
                      : "var(--border-strong)",
                  }}
                />
                {errors.phone ? (
                  <span id="pilot-phone-error" style={fieldErrorStyle}>
                    {errors.phone}
                  </span>
                ) : null}
              </div>

              {/* Email */}
              <div>
                <label htmlFor="pilot-email" style={labelStyle}>
                  Email
                </label>
                <input
                  id="pilot-email"
                  name="email"
                  type="email"
                  value={form.email}
                  onChange={handleChange}
                  onBlur={handleBlur}
                  maxLength={PILOT_LIMITS.email.max}
                  placeholder="alex@prinzip.ru"
                  aria-invalid={errors.email ? "true" : "false"}
                  aria-describedby={
                    errors.email ? "pilot-email-error" : undefined
                  }
                  style={{
                    ...inputStyle,
                    borderColor: errors.email
                      ? "var(--danger)"
                      : "var(--border-strong)",
                  }}
                />
                {errors.email ? (
                  <span id="pilot-email-error" style={fieldErrorStyle}>
                    {errors.email}
                  </span>
                ) : null}
              </div>

              {/* Message */}
              <div>
                <label htmlFor="pilot-message" style={labelStyle}>
                  Сообщение
                </label>
                <textarea
                  id="pilot-message"
                  name="message"
                  value={form.message}
                  onChange={handleChange}
                  onBlur={handleBlur}
                  placeholder="Расскажите о вашем проекте или вопросе..."
                  rows={4}
                  maxLength={PILOT_LIMITS.message.max}
                  aria-invalid={errors.message ? "true" : "false"}
                  aria-describedby={
                    errors.message ? "pilot-message-error" : undefined
                  }
                  style={{
                    ...inputStyle,
                    resize: "vertical",
                    minHeight: 96,
                    fontFamily: "inherit",
                    borderColor: errors.message
                      ? "var(--danger)"
                      : "var(--border-strong)",
                  }}
                />
                <span
                  style={{
                    fontSize: 12,
                    color: "var(--fg-tertiary)",
                    marginTop: 2,
                    display: "block",
                  }}
                >
                  {form.message.length} / {PILOT_LIMITS.message.max}
                </span>
                {errors.message ? (
                  <span id="pilot-message-error" style={fieldErrorStyle}>
                    {errors.message}
                  </span>
                ) : null}
              </div>

              {/* Error */}
              {mutation.isError ? (
                <div
                  role="alert"
                  style={{
                    padding: "10px 14px",
                    background: "var(--danger-soft)",
                    borderRadius: 8,
                    fontSize: 13,
                    color: "var(--danger)",
                  }}
                >
                  {formatSubmitError(mutation.error)}
                </div>
              ) : null}

              {/* Submit */}
              <button
                type="submit"
                disabled={submitDisabled}
                style={{
                  padding: "12px 24px",
                  background: submitDisabled
                    ? "var(--accent-soft)"
                    : "var(--accent)",
                  color: submitDisabled ? "var(--accent)" : "#fff",
                  border: "none",
                  borderRadius: 8,
                  fontSize: 15,
                  fontWeight: 600,
                  cursor: submitDisabled ? "not-allowed" : "pointer",
                  opacity: submitDisabled ? 0.7 : 1,
                  transition: "opacity 0.15s",
                }}
              >
                {mutation.isPending ? "Отправка..." : "Отправить заявку"}
              </button>
            </div>
          </form>
        )}
      </div>
    </Drawer>
  );
}

// ── Shared styles ──────────────────────────────────────────────────────────

const labelStyle: React.CSSProperties = {
  display: "block",
  fontSize: 12,
  fontWeight: 500,
  textTransform: "uppercase" as const,
  letterSpacing: "0.04em",
  color: "var(--fg-secondary)",
  marginBottom: 6,
};

const inputStyle: React.CSSProperties = {
  width: "100%",
  padding: "9px 12px",
  border: "1px solid var(--border-strong)",
  borderRadius: 8,
  fontSize: 14,
  color: "var(--fg-primary)",
  background: "var(--bg-card)",
  outline: "none",
  boxSizing: "border-box" as const,
};

const fieldErrorStyle: React.CSSProperties = {
  fontSize: 12,
  color: "var(--danger)",
  marginTop: 4,
  display: "block",
};
