"use client";

import { ForgotPasswordWizard, validationMessages, isCompletePersonIdentifier, sanitizePersonIdentifier } from "@school/ui";
import { useRouter } from "next/navigation";
import { FormEvent, useEffect, useMemo, useState } from "react";
import { BrandingStyles } from "@/components/app/BrandingStyles";
import { Alert } from "@/components/ui/Alert";
import { Button } from "@/components/ui/Button";
import { Field, Input } from "@/components/ui/Field";
import {
  ApiError,
  Branding,
  allowsAppTarget,
  apiGet,
  fetchCaptcha,
  forgotPassword,
  getStoredUser,
  login,
  PORTAL_APP_URL,
  requestLoginOtp,
  resetPassword,
  retryAfterSeconds,
  verifyCredentials,
  verifyForgotOtp,
  type AdminUser,
} from "@/lib/api";
import { brandingLogoUrl } from "@/lib/branding";

type Mode = "login" | "forgot";
type LoginStep = "credentials" | "otp";

export default function LoginPage() {
  const router = useRouter();
  const [branding, setBranding] = useState<Branding | null>(null);
  const [mode, setMode] = useState<Mode>("login");
  const [loginStep, setLoginStep] = useState<LoginStep>("credentials");
  const [nationalCode, setNationalCode] = useState("");
  const [isForeign, setIsForeign] = useState(false);
  const [password, setPassword] = useState("");
  const [otp, setOtp] = useState("");
  const [loading, setLoading] = useState(false);
  const [otpLoading, setOtpLoading] = useState(false);
  const [otpRetryAfter, setOtpRetryAfter] = useState(0);
  const [error, setError] = useState<string | null>(null);
  const [info, setInfo] = useState<string | null>(null);

  const forgotApi = useMemo(
    () => ({
      fetchCaptcha,
      forgotPassword,
      verifyForgotOtp,
      resetPassword,
    }),
    [],
  );

  useEffect(() => {
    apiGet<Branding>("/branding").then(setBranding).catch(() => null);
  }, []);

  useEffect(() => {
    if (otpRetryAfter <= 0) {
      return;
    }
    const timer = window.setTimeout(() => setOtpRetryAfter((value) => Math.max(0, value - 1)), 1000);
    return () => window.clearTimeout(timer);
  }, [otpRetryAfter]);

  const resetLoginFlow = () => {
    setLoginStep("credentials");
    setOtp("");
    setError(null);
    setInfo(null);
    setOtpRetryAfter(0);
  };

  const identifier = () => sanitizePersonIdentifier(nationalCode, isForeign).trim();

  const completeLogin = async () => {
    await login(identifier(), password, otp.trim());
    const stored = getStoredUser<AdminUser>();
    router.replace(stored?.password_change_required ? "/change-password" : "/select-context");
  };

  const verifyAndContinue = async () => {
    const code = identifier();
    if (!isCompletePersonIdentifier(code, isForeign)) {
      setError(isForeign ? "شناسه اتباع الزامی است." : validationMessages.nationalCodeLength);
      return;
    }
    if (!password) {
      setError(validationMessages.required("رمز عبور"));
      return;
    }

    setLoading(true);
    setError(null);
    setInfo(null);

    try {
      const result = await verifyCredentials(code, password);

      if (!allowsAppTarget(result, "admin")) {
        throw new ApiError("این حساب برای پنل مدیریت مجاز نیست.", 403);
      }

      if (!result.requires_otp) {
        await completeLogin();
        return;
      }

      setLoginStep("otp");
      setOtpRetryAfter(result.retry_after ?? (result.otp_sent ? 60 : 0));
      setInfo(
        result.otp_sent
          ? "رمز یک‌بارمصرف به شماره همراه شما ارسال شد."
          : "رمز یک‌بارمصرف قبلاً ارسال شده است. پس از اتمام زمان می‌توانید دوباره درخواست کنید.",
      );
    } catch (err) {
      setError(err instanceof ApiError ? err.message : "خطا در تأیید اطلاعات ورود");
    } finally {
      setLoading(false);
    }
  };

  const sendOtp = async () => {
    const code = identifier();
    if (!isCompletePersonIdentifier(code, isForeign)) {
      setError(isForeign ? "شناسه اتباع الزامی است." : validationMessages.nationalCodeLength);
      return;
    }
    setOtpLoading(true);
    setError(null);
    setInfo(null);
    try {
      const data = await requestLoginOtp(code, "login");
      setOtpRetryAfter(data.retry_after ?? 60);
      setInfo("رمز یک‌بارمصرف به شماره همراه شما ارسال شد.");
    } catch (err) {
      if (err instanceof ApiError) {
        const wait = retryAfterSeconds(err);
        if (wait > 0) {
          setOtpRetryAfter(wait);
        }
        setError(err.message);
      } else {
        setError("خطا در ارسال رمز یک‌بارمصرف");
      }
    } finally {
      setOtpLoading(false);
    }
  };

  const onSubmit = async (event: FormEvent) => {
    event.preventDefault();
    setLoading(true);
    setError(null);
    setInfo(null);

    try {
      if (loginStep === "credentials") {
        await verifyAndContinue();
        return;
      }

      if (!otp.trim()) {
        setError(validationMessages.otpRequired);
        return;
      }

      await completeLogin();
    } catch (err) {
      setError(err instanceof ApiError ? err.message : "خطای غیرمنتظره");
    } finally {
      setLoading(false);
    }
  };

  const primary = branding?.primary_color ?? "#0d9488";

  return (
    <div className="min-h-screen">
      {branding ? <BrandingStyles branding={branding} /> : null}
      <div
        className="px-4 py-10 text-white"
        style={{
          background: `linear-gradient(135deg, ${primary} 0%, color-mix(in srgb, ${primary} 65%, #0f172a) 100%)`,
        }}
      >
        <div className="mx-auto max-w-md text-center">
          {brandingLogoUrl(branding?.logo_url) ? (
            // eslint-disable-next-line @next/next/no-img-element
            <img
              src={brandingLogoUrl(branding?.logo_url)!}
              alt=""
              className="mx-auto mb-3 h-16 w-16 rounded-2xl bg-white/10 object-contain"
            />
          ) : null}
          <h1 className="text-2xl font-bold">{branding?.admin_title ?? "پنل مدیریت"}</h1>
          <p className="mt-1 text-sm text-white/80">{branding?.name ?? "سامانه مدیریت مدارس"}</p>
        </div>
      </div>

      <div className="mx-auto -mt-8 max-w-md px-4 pb-10">
        <div className="overflow-hidden rounded-3xl border border-[var(--border)] bg-white p-6 shadow-card">
          <div className="mb-4 flex gap-2 text-sm">
            <button
              type="button"
              className={`rounded-lg px-3 py-1.5 font-semibold ${mode === "login" ? "bg-slate-100" : "text-[var(--muted)]"}`}
              onClick={() => {
                setMode("login");
                resetLoginFlow();
              }}
            >
              ورود
            </button>
            <button
              type="button"
              className={`rounded-lg px-3 py-1.5 font-semibold ${mode === "forgot" ? "bg-slate-100" : "text-[var(--muted)]"}`}
              onClick={() => {
                setMode("forgot");
                resetLoginFlow();
              }}
            >
              فراموشی رمز
            </button>
          </div>

          {mode === "forgot" ? (
            <ForgotPasswordWizard
              api={forgotApi}
              onSuccess={(message) => {
                setInfo(`${message} اکنون وارد شوید.`);
                setMode("login");
                resetLoginFlow();
                setPassword("");
              }}
            />
          ) : (
            <form onSubmit={onSubmit}>
              {error ? (
                <div className="mb-4">
                  <Alert tone="error">{error}</Alert>
                </div>
              ) : null}
              {info ? (
                <div className="mb-4">
                  <Alert tone="success">{info}</Alert>
                </div>
              ) : null}

              {loginStep === "otp" ? (
                <button
                  type="button"
                  className="mb-4 text-xs font-medium text-primary hover:underline"
                  onClick={resetLoginFlow}
                >
                  ← بازگشت به مرحله قبل
                </button>
              ) : null}

              <label className="mb-3 flex items-center gap-2 text-sm">
                <input
                  type="checkbox"
                  checked={isForeign}
                  disabled={loginStep === "otp"}
                  onChange={(e) => {
                    setIsForeign(e.target.checked);
                    setNationalCode((current) => sanitizePersonIdentifier(current, e.target.checked));
                  }}
                />
                اتباع هستم
              </label>
              <Field label={isForeign ? "شناسه اتباع" : "کد ملی"}>
                <Input
                  inputMode={isForeign ? "text" : "numeric"}
                  autoComplete="username"
                  maxLength={isForeign ? 30 : 10}
                  value={nationalCode}
                  onChange={(e) => setNationalCode(sanitizePersonIdentifier(e.target.value, isForeign))}
                  required
                  disabled={loginStep === "otp"}
                />
              </Field>

              {loginStep === "credentials" ? (
                <div className="mt-4">
                  <Field label="رمز عبور">
                    <Input
                      type="password"
                      autoComplete="current-password"
                      value={password}
                      onChange={(e) => setPassword(e.target.value)}
                      required
                    />
                  </Field>
                </div>
              ) : (
                <div className="mt-4">
                  <Field label="رمز یک‌بارمصرف (OTP)">
                    <div className="flex gap-2">
                      <Input
                        inputMode="numeric"
                        autoComplete="one-time-code"
                        value={otp}
                        onChange={(e) => setOtp(e.target.value.replace(/\D/g, "").slice(0, 8))}
                        required
                        className="flex-1"
                      />
                      <Button
                        type="button"
                        variant="secondary"
                        loading={otpLoading}
                        disabled={otpRetryAfter > 0}
                        onClick={sendOtp}
                      >
                        {otpRetryAfter > 0 ? `ارسال مجدد (${otpRetryAfter})` : "ارسال مجدد"}
                      </Button>
                    </div>
                  </Field>
                  <p className="mt-1 text-xs text-[var(--muted)]">
                    کد در پیام رسان بله و همچنین از طریق پیامک ارسال شد. ارسال مجدد هر ۶۰ ثانیه یک‌بار ممکن است.
                  </p>
                </div>
              )}

              <Button type="submit" block loading={loading} className="mt-5">
                {loginStep === "credentials" ? "ادامه" : "ورود"}
              </Button>
            </form>
          )}

          <p className="mt-4 text-center text-xs text-[var(--muted)]">
            دانش‌آموز یا والدین هستید؟{" "}
            <a href={`${PORTAL_APP_URL}/login`} className="font-semibold text-primary hover:underline">
              ورود به پنل دانش‌آموزی و والدین
            </a>
          </p>
          <p className="mt-2 text-center text-xs">
            <a href={PORTAL_APP_URL} className="text-[var(--muted)] hover:underline">
              بازگشت به صفحه اصلی
            </a>
          </p>
        </div>
      </div>
    </div>
  );
}
