"use client";

import { useState } from "react";
import { useTranslations } from "next-intl";
import { Button, Card, CardContent, CardDescription, CardHeader, CardTitle } from "@hexahost/ui";
import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";
import { ApiError, confirmTwoFactor, setupTwoFactor, type TwoFactorSetupResponse } from "@/lib/api/auth";
import { createTwoFactorSchema, type TwoFactorFormValues } from "@/lib/schemas/auth";
import { useAuth } from "@/components/providers/auth-provider";

const inputClassName =
  "flex h-10 w-full rounded-md border border-zinc-300 bg-white px-3 text-sm text-zinc-900 placeholder:text-zinc-400 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-sky-500 dark:border-zinc-700 dark:bg-zinc-950 dark:text-zinc-100";

export function SecurityContent() {
  const t = useTranslations("auth");
  const tv = useTranslations("validation");
  const { user, refresh } = useAuth();
  const [setup, setSetup] = useState<TwoFactorSetupResponse | null>(null);
  const [apiError, setApiError] = useState<string | null>(null);
  const [confirmed, setConfirmed] = useState(false);
  const [isStarting, setIsStarting] = useState(false);

  const schema = createTwoFactorSchema({
    codeRequired: tv("codeRequired"),
    codeInvalid: tv("codeInvalid"),
  });

  const {
    register,
    handleSubmit,
    formState: { errors, isSubmitting },
  } = useForm<TwoFactorFormValues>({
    resolver: zodResolver(schema),
    defaultValues: { code: "" },
  });

  async function handleStartSetup() {
    setApiError(null);
    setIsStarting(true);

    try {
      const response = await setupTwoFactor();
      setSetup(response);
    } catch (error) {
      if (error instanceof ApiError) {
        setApiError(error.detail ?? error.title);
      } else {
        setApiError(t("errors.generic"));
      }
    } finally {
      setIsStarting(false);
    }
  }

  async function onSubmit(values: TwoFactorFormValues) {
    setApiError(null);

    try {
      await confirmTwoFactor(values.code);
      setConfirmed(true);
      setSetup(null);
      await refresh();
    } catch (error) {
      if (error instanceof ApiError) {
        setApiError(error.detail ?? error.title);
      } else {
        setApiError(t("errors.generic"));
      }
    }
  }

  return (
    <div className="space-y-6">
      <div>
        <h1 className="text-2xl font-semibold tracking-tight text-zinc-900 dark:text-zinc-50">
          {t("securityTitle")}
        </h1>
        <p className="mt-1 text-sm text-zinc-600 dark:text-zinc-400">{t("securitySubtitle")}</p>
      </div>

      <Card>
        <CardHeader>
          <CardTitle>{t("twoFactorSetupTitle")}</CardTitle>
          <CardDescription>
            {user?.twoFactorEnabled ? t("twoFactorEnabled") : t("twoFactorSetupDescription")}
          </CardDescription>
        </CardHeader>
        <CardContent className="space-y-4">
          {user?.twoFactorEnabled || confirmed ? (
            <p className="rounded-md border border-emerald-200 bg-emerald-50 px-3 py-2 text-sm text-emerald-900 dark:border-emerald-900 dark:bg-emerald-950 dark:text-emerald-100">
              {t("twoFactorEnabled")}
            </p>
          ) : null}

          {!user?.twoFactorEnabled && !confirmed && !setup ? (
            <Button onClick={handleStartSetup} isLoading={isStarting}>
              {t("twoFactorSetupStart")}
            </Button>
          ) : null}

          {setup ? (
            <div className="space-y-4">
              <p className="text-sm text-zinc-600 dark:text-zinc-400">{t("twoFactorScanQr")}</p>
              {/* eslint-disable-next-line @next/next/no-img-element */}
              <img
                src={setup.qrCodeUrl}
                alt={t("twoFactorQrAlt")}
                className="h-48 w-48 rounded-md border border-zinc-200 dark:border-zinc-800"
              />
              <p className="font-mono text-xs text-zinc-500">{setup.secret}</p>

              {setup.recoveryCodes?.length ? (
                <div className="rounded-md border border-amber-200 bg-amber-50 p-3 dark:border-amber-900 dark:bg-amber-950">
                  <p className="mb-2 text-sm font-medium text-amber-900 dark:text-amber-100">
                    {t("recoveryCodesTitle")}
                  </p>
                  <ul className="grid gap-1 font-mono text-xs text-amber-900 dark:text-amber-100 sm:grid-cols-2">
                    {setup.recoveryCodes.map((code) => (
                      <li key={code}>{code}</li>
                    ))}
                  </ul>
                </div>
              ) : null}

              <form onSubmit={handleSubmit(onSubmit)} className="space-y-4" noValidate>
                <div className="space-y-2">
                  <label htmlFor="code" className="text-sm font-medium text-zinc-900 dark:text-zinc-100">
                    {t("twoFactorCode")}
                  </label>
                  <input
                    id="code"
                    type="text"
                    inputMode="numeric"
                    autoComplete="one-time-code"
                    placeholder="000000"
                    maxLength={6}
                    aria-invalid={errors.code ? "true" : "false"}
                    className={inputClassName}
                    {...register("code")}
                  />
                  {errors.code ? (
                    <p className="text-sm text-red-600" role="alert">
                      {errors.code.message}
                    </p>
                  ) : null}
                </div>

                {apiError ? (
                  <p className="rounded-md border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-900 dark:border-red-900 dark:bg-red-950 dark:text-red-100" role="alert">
                    {apiError}
                  </p>
                ) : null}

                <Button type="submit" isLoading={isSubmitting}>
                  {t("twoFactorConfirm")}
                </Button>
              </form>
            </div>
          ) : null}

          {apiError && !setup ? (
            <p className="rounded-md border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-900 dark:border-red-900 dark:bg-red-950 dark:text-red-100" role="alert">
              {apiError}
            </p>
          ) : null}
        </CardContent>
      </Card>
    </div>
  );
}
