import { useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";
import { useMutation } from "@tanstack/react-query";
import { HTTPError } from "ky";
import { toast } from "sonner";
import { login, login2fa } from "@/api/auth";
import { getMe } from "@/api/me";
import { useAuth } from "@/store/auth";
import {
  clearRevocation,
  readRevocation,
  storeRevocation,
  type RevocationInfo,
} from "@/hooks/useMeSync";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";

type Step =
  | { kind: "credentials" }
  | { kind: "totp"; partialToken: string };

export default function Login() {
  const navigate = useNavigate();
  const setToken = useAuth((s) => s.setToken);

  const [step, setStep] = useState<Step>({ kind: "credentials" });
  const [username, setUsername] = useState("");
  const [password, setPassword] = useState("");
  const [code, setCode] = useState("");
  const [rememberDevice, setRememberDevice] = useState(true);

  // У36: показываем явное сообщение «доступ отозван» с кликабельным контактом,
  // если пользователь только что был выкинут из приложения фоновой сверкой (У35)
  // или получил 403 NO_PWA_ACCESS при последней попытке логина.
  const [revocation, setRevocation] = useState<RevocationInfo | null>(() => readRevocation());

  // У36: после успешной аутентификации проверяем доступ к PWA через /me.
  // /auth/login универсальный (используется и CRM, и PWA), поэтому
  // отказ в PWA-доступе различается именно по ответу /me (403 NO_PWA_ACCESS).
  const verifyPwaAccessAndNavigate = async (token: string) => {
    setToken(token);
    try {
      await getMe();
      clearRevocation();
      setRevocation(null);
      toast.success("Вход выполнен");
      navigate("/", { replace: true });
    } catch (err) {
      if (err instanceof HTTPError && err.response.status === 403) {
        let detail: unknown = null;
        try {
          const body = (await err.response.json()) as { detail?: unknown };
          detail = body?.detail ?? null;
        } catch {
          /* not JSON */
        }
        storeRevocation(detail);
        setRevocation(readRevocation());
        setToken(null);
      } else {
        toast.error("Не удалось проверить доступ к приложению");
      }
    }
  };

  // Если revocation сохранён сессией — очищаем при ручной смене ввода логина.
  useEffect(() => {
    if (revocation && (username || password)) {
      clearRevocation();
      setRevocation(null);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [username, password]);

  const loginMutation = useMutation({
    mutationFn: login,
    onSuccess: (data) => {
      if (data.requires_2fa && data.partial_token) {
        setStep({ kind: "totp", partialToken: data.partial_token });
        setCode("");
        toast.info("Нужен код 2FA");
        return;
      }
      if (data.access_token) {
        // У36: проверяем доступ к PWA через /me перед навигацией.
        void verifyPwaAccessAndNavigate(data.access_token);
        return;
      }
      toast.error("Неожиданный ответ сервера");
    },
    onError: () => toast.error("Неверный логин или пароль"),
  });

  const twoFaMutation = useMutation({
    mutationFn: login2fa,
    onSuccess: (data) => {
      if (data.access_token) {
        void verifyPwaAccessAndNavigate(data.access_token);
      } else {
        toast.error("Сервер не вернул токен");
      }
    },
    onError: () => toast.error("Неверный код 2FA"),
  });

  return (
    <div className="min-h-screen flex items-center justify-center bg-background p-4">
      <div className="w-full max-w-sm bg-card rounded-2xl shadow-sm p-6 space-y-4">
        <h1 className="text-2xl font-semibold text-foreground">Premium Механик</h1>

        {revocation && (
          <div className="rounded-md border border-amber-300 bg-amber-50 p-3 text-sm text-amber-900">
            <div className="font-medium mb-1">У вас нет доступа к PWA Premium Мехник</div>
            <div>
              Обратитесь к старшему механику или администратору CRM
              {(() => {
                const tg = revocation.support?.tg_username;
                const phone = revocation.support?.phone;
                if (tg) {
                  return (
                    <>
                      {": "}
                      <a
                        href={`https://t.me/${tg}`}
                        target="_blank"
                        rel="noreferrer"
                        className="underline font-medium"
                      >
                        @{tg}
                      </a>
                      {phone ? (
                        <>
                          {" · "}
                          <a href={`tel:${phone}`} className="underline font-medium">{phone}</a>
                        </>
                      ) : null}
                    </>
                  );
                }
                if (phone) {
                  return (
                    <>
                      {": "}
                      <a href={`tel:${phone}`} className="underline font-medium">{phone}</a>
                    </>
                  );
                }
                return ".";
              })()}
            </div>
          </div>
        )}

        {step.kind === "credentials" && (
          <>
            <p className="text-sm text-muted-foreground">
              Войдите учётной записью TaxiDashboard.
            </p>
            <form
              onSubmit={(e) => {
                e.preventDefault();
                loginMutation.mutate({ username, password });
              }}
              className="space-y-3"
            >
              <div className="space-y-1">
                <Label htmlFor="username">Логин</Label>
                <Input
                  id="username"
                  type="text"
                  autoComplete="username"
                  value={username}
                  onChange={(e) => setUsername(e.target.value)}
                  required
                  autoFocus
                />
              </div>
              <div className="space-y-1">
                <Label htmlFor="password">Пароль</Label>
                <Input
                  id="password"
                  type="password"
                  autoComplete="current-password"
                  value={password}
                  onChange={(e) => setPassword(e.target.value)}
                  required
                />
              </div>
              <Button type="submit" disabled={loginMutation.isPending} className="w-full">
                {loginMutation.isPending ? "Входим…" : "Войти"}
              </Button>
            </form>
          </>
        )}

        {step.kind === "totp" && (
          <>
            <p className="text-sm text-muted-foreground">
              Введите 6-значный код из приложения-аутентификатора (Google
              Authenticator, Aegis, 1Password, и т. п.).
            </p>
            <form
              onSubmit={(e) => {
                e.preventDefault();
                twoFaMutation.mutate({
                  partial_token: step.partialToken,
                  code: code.trim(),
                  remember_device: rememberDevice,
                });
              }}
              className="space-y-3"
            >
              <div className="space-y-1">
                <Label htmlFor="totp">Код 2FA</Label>
                <Input
                  id="totp"
                  type="text"
                  inputMode="numeric"
                  autoComplete="one-time-code"
                  pattern="[0-9]{6}"
                  maxLength={6}
                  value={code}
                  onChange={(e) => setCode(e.target.value.replace(/\D/g, "").slice(0, 6))}
                  required
                  autoFocus
                />
              </div>
              <label className="flex items-center gap-2 text-sm text-muted-foreground select-none">
                <input
                  type="checkbox"
                  checked={rememberDevice}
                  onChange={(e) => setRememberDevice(e.target.checked)}
                />
                Запомнить это устройство на 30 дней
              </label>
              <Button
                type="submit"
                disabled={twoFaMutation.isPending || code.length !== 6}
                className="w-full"
              >
                {twoFaMutation.isPending ? "Проверяем…" : "Войти"}
              </Button>
              <button
                type="button"
                onClick={() => {
                  setStep({ kind: "credentials" });
                  setPassword("");
                  setCode("");
                }}
                className="w-full text-xs text-muted-foreground hover:text-foreground"
              >
                ← Назад
              </button>
            </form>
          </>
        )}
      </div>
    </div>
  );
}
