"use client"

import { useState } from "react"
import axios from "axios"
import Link from "next/link"
import { useRouter } from "next/navigation"
import { Lock, Mail, ShieldCheck, ArrowLeft, ArrowRight, Loader2, KeyRound, Eye, EyeOff } from "lucide-react"
import { persistAuthAction } from "@/app/login/actions"
import { api } from "@/lib/api"
import { ENDPOINTS } from "@/constants/endpoints"
import { useAuth } from "@/contexts/auth-context"
import type { ApiResponse, UserDTO } from "@/types"
import i18n from "@/lib/i18n";

function mapUserToAuth(user: UserDTO) {
  return {
    id: user.id,
    name: user.email?.split("@")[0] || i18n.t('components.auth.login-form.text_1'),
    email: user.email || "",
    role: user.roles?.[0]?.code || user.user_type || "operations_admin",
    roles: user.roles || [],
    permissions: user.permissions || [],
    user_type: user.user_type,
    status: user.status,
  }
}

type Step = "credentials" | "mustChangePassword" | "otp"

type LoginTokens = {
  access_token: string
  refresh_token: string
  token_type: string
  session_id: string
  user: UserDTO
}

function loginError(error: unknown, fallback: string, statusMessages: Record<number, string>): string {
  if (!axios.isAxiosError(error)) return error instanceof Error ? error.message : fallback
  const status = error.response?.status || 0
  const payload = error.response?.data as {
    message?: unknown
    trace_id?: unknown
    data?: { error_code?: unknown; field_errors?: Record<string, string[]> }
  } | undefined
  const readableMessage = typeof payload?.message === "string" && !/^[-a-z0-9_.]+$/i.test(payload.message)
    ? payload.message
    : statusMessages[status] || fallback
  const fields = payload?.data?.field_errors
    ? Object.values(payload.data.field_errors).flat().slice(0, 3).join("\n")
    : ""
  const traceId = typeof payload?.trace_id === "string" ? payload.trace_id : error.response?.headers?.["x-request-id"]
  return [fields || readableMessage, traceId ? `${i18n.t('components.auth.login-form.text_26', { defaultValue: 'Reference' })}: ${traceId}` : ""]
    .filter(Boolean)
    .join("\n")
}

export function LoginForm() {
  const router = useRouter()
  const { setAuth } = useAuth()
  const [username, setUsername] = useState("")
  const [password, setPassword] = useState("")
  const [otpCode, setOtpCode] = useState("")
  const [newPassword, setNewPassword] = useState("")
  const [confirmPassword, setConfirmPassword] = useState("")
  const [showPassword, setShowPassword] = useState(false)
  const [showNewPassword, setShowNewPassword] = useState(false)

  const [step, setStep] = useState<Step>("credentials")
  const [preAuthToken, setPreAuthToken] = useState("")

  const [error, setError] = useState<string | null>(null)
  const [loading, setLoading] = useState(false)

  async function onSubmitCredentials(e: React.FormEvent) {
    e.preventDefault()
    setLoading(true)
    setError(null)

    try {
      const response: ApiResponse<{ pre_auth_token: string; message: string; must_change_password?: boolean }> = await api.post(
        ENDPOINTS.AUTH.LOGIN_STEP1,
        { username: username.trim(), password },
      ) as ApiResponse<{ pre_auth_token: string; message: string; must_change_password?: boolean }>
      if (!response.success || !response.data?.pre_auth_token) throw new Error(response.message)

      if (response.data.must_change_password) {
        setPreAuthToken(response.data.pre_auth_token)
        setNewPassword(password)
        setConfirmPassword(password)
        setStep("mustChangePassword")
        setLoading(false)
      } else {
        setPreAuthToken(response.data.pre_auth_token)
        setStep("otp")
        setLoading(false)
      }
    } catch (err: unknown) {
      setError(loginError(err, i18n.t('components.auth.login-form.text_2'), {
        401: i18n.t('app.login.actions.text_6'),
        403: i18n.t('app.login.actions.text_5'),
        422: i18n.t('components.auth.login-form.text_2'),
        429: i18n.t('app.login.actions.text_7'),
      }))
      setLoading(false)
    }
  }

  async function onSubmitTempPassword(e: React.FormEvent) {
    e.preventDefault()
    setLoading(true)
    setError(null)

    if (newPassword !== confirmPassword) {
      setError(i18n.t('components.auth.login-form.text_3'))
      setLoading(false)
      return
    }

    if (newPassword.length < 8) {
      setError(i18n.t('components.auth.login-form.text_4'))
      setLoading(false)
      return
    }

    try {
      const response: ApiResponse<LoginTokens> = await api.post(ENDPOINTS.AUTH.CHANGE_TEMP_PASSWORD, {
        pre_auth_token: preAuthToken,
        new_password: newPassword,
      }) as ApiResponse<LoginTokens>
      if (!response.success || !response.data?.access_token) throw new Error(response.message)
      const persisted = await persistAuthAction({
        accessToken: response.data.access_token,
        refreshToken: response.data.refresh_token,
        tokenType: response.data.token_type,
        sessionId: response.data.session_id,
        user: response.data.user,
      })
      if (!persisted.success || !persisted.user || !persisted.accessToken) {
        throw new Error(persisted.message)
      }
      setAuth(persisted.accessToken, mapUserToAuth(persisted.user))
      router.push(persisted.redirectPath || "/")
      router.refresh()
    } catch (err: unknown) {
      setError(loginError(err, i18n.t('components.auth.login-form.text_5'), {
        400: i18n.t('app.login.actions.text_22'),
        401: i18n.t('app.login.actions.text_21'),
        422: i18n.t('components.auth.login-form.text_5'),
        429: i18n.t('app.login.actions.text_7'),
      }))
      setLoading(false)
    }
  }

  async function onSubmitOtp(e: React.FormEvent) {
    e.preventDefault()
    setLoading(true)
    setError(null)

    try {
      const response: ApiResponse<LoginTokens> = await api.post(ENDPOINTS.AUTH.LOGIN_VERIFY_OTP, {
        pre_auth_token: preAuthToken,
        otp_code: otpCode.trim(),
      }) as ApiResponse<LoginTokens>
      if (!response.success || !response.data?.access_token) throw new Error(response.message)
      const persisted = await persistAuthAction({
        accessToken: response.data.access_token,
        refreshToken: response.data.refresh_token,
        tokenType: response.data.token_type,
        sessionId: response.data.session_id,
        user: response.data.user,
      })
      if (!persisted.success || !persisted.user || !persisted.accessToken) {
        throw new Error(persisted.message)
      }
      setAuth(persisted.accessToken, mapUserToAuth(persisted.user))
      router.push(persisted.redirectPath || "/")
      router.refresh()
    } catch (err: unknown) {
      setError(loginError(err, i18n.t('components.auth.login-form.text_6'), {
        401: i18n.t('app.login.actions.text_13'),
        410: i18n.t('app.login.actions.text_14'),
        422: i18n.t('components.auth.login-form.text_6'),
        429: i18n.t('app.login.actions.text_15'),
      }))
      setLoading(false)
    }
  }

  function onGoBack() {
    setStep("credentials")
    setOtpCode("")
    setNewPassword("")
    setConfirmPassword("")
    setError(null)
    setPreAuthToken("")
  }

  if (step === "mustChangePassword") {
    return (
      <form className="space-y-4" onSubmit={onSubmitTempPassword}>
        <div className="text-center pb-2">
          <div className="inline-flex h-12 w-12 items-center justify-center rounded-full bg-amber-50 text-amber-600 mb-2">
            <KeyRound className="h-6 w-6" />
          </div>
          <h3 className="text-[16px] font-bold text-foreground">{i18n.t('components.auth.login-form.text_7')}</h3>
          <p className="text-[12px] text-muted-foreground mt-1">
            {i18n.t('components.auth.login-form.text_8')}</p>
        </div>

        <div>
          <label className="block text-[12.5px] font-semibold text-foreground mb-1.5">{i18n.t('components.auth.login-form.text_9')}</label>
          <div className="relative">
            <Lock className="absolute right-3 top-1/2 -translate-y-1/2 h-[17px] w-[17px] text-muted-foreground" />
            <input
              type={showNewPassword ? "text" : "password"}
              required
              value={newPassword}
              onChange={(e) => setNewPassword(e.target.value)}
              className="w-full h-11 pr-10 pl-10 rounded-lg border border-border bg-card text-[13.5px] tracking-widest focus:outline-none focus:border-gold-500 focus:ring-2 focus:ring-gold-500/20 transition"
            />
            <button
              type="button"
              onClick={() => setShowNewPassword(!showNewPassword)}
              className="absolute left-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground"
            >
              {showNewPassword ? <EyeOff className="h-4 w-4" /> : <Eye className="h-4 w-4" />}
            </button>
          </div>
        </div>

        <div>
          <label className="block text-[12.5px] font-semibold text-foreground mb-1.5">{i18n.t('components.auth.login-form.text_10')}</label>
          <div className="relative">
            <Lock className="absolute right-3 top-1/2 -translate-y-1/2 h-[17px] w-[17px] text-muted-foreground" />
            <input
              type="password"
              required
              value={confirmPassword}
              onChange={(e) => setConfirmPassword(e.target.value)}
              className="w-full h-11 pr-10 pl-4 rounded-lg border border-border bg-card text-[13.5px] tracking-widest focus:outline-none focus:border-gold-500 focus:ring-2 focus:ring-gold-500/20 transition"
            />
          </div>
        </div>

        {error && (
          <div className="whitespace-pre-line rounded-lg bg-red-50 border border-red-200 px-3 py-2.5 text-[12.5px] text-red-700">
            {error}
          </div>
        )}

        <button
          type="submit"
          disabled={loading}
          className="w-full h-11 mt-2 rounded-lg bg-gradient-to-b from-gold-500 to-gold-600 hover:from-gold-600 hover:to-gold-700 text-white font-semibold text-[13.5px] inline-flex items-center justify-center gap-2 shadow-[0_4px_14px_rgba(201,162,39,0.3)] hover:shadow-[0_6px_18px_rgba(201,162,39,0.4)] transition disabled:opacity-70"
        >
          {loading ? <Loader2 className="h-4 w-4 animate-spin" /> : (
            <>
              {i18n.t('components.auth.login-form.text_11')}<ArrowLeft className="h-4 w-4" />
            </>
          )}
        </button>

        <button
          type="button"
          onClick={onGoBack}
          disabled={loading}
          className="w-full h-10 mt-1 rounded-lg border border-border hover:bg-muted/50 text-muted-foreground font-medium text-[12.5px] inline-flex items-center justify-center gap-1.5 transition"
        >
          <ArrowRight className="h-3.5 w-3.5" />
          {i18n.t('components.auth.login-form.text_12')}</button>
      </form>
    )
  }

  if (step === "otp") {
    return (
      <form className="space-y-4" onSubmit={onSubmitOtp}>
        <div className="text-center pb-2">
          <div className="inline-flex h-12 w-12 items-center justify-center rounded-full bg-gold-50 text-gold-600 mb-2">
            <KeyRound className="h-6 w-6" />
          </div>
          <h3 className="text-[16px] font-bold text-foreground">{i18n.t('components.auth.login-form.text_13')}</h3>
          <p className="text-[12px] text-muted-foreground mt-1">
            {i18n.t('components.auth.login-form.text_14')}</p>
        </div>

        <div>
          <label className="block text-[12.5px] font-semibold text-foreground mb-1.5">{i18n.t('components.auth.login-form.text_15')}</label>
          <div className="relative">
            <Lock className="absolute right-3 top-1/2 -translate-y-1/2 h-[17px] w-[17px] text-muted-foreground" />
            <input
              type="text"
              required
              value={otpCode}
              onChange={(e) => setOtpCode(e.target.value)}
              className="w-full h-11 pr-10 pl-4 rounded-lg border border-border bg-card text-[15px] font-mono tracking-[0.5em] text-center focus:outline-none focus:border-gold-500 focus:ring-2 focus:ring-gold-500/20 transition"
              placeholder="000000"
              maxLength={8}
              autoFocus
            />
          </div>
        </div>

        {error && (
          <div className="whitespace-pre-line rounded-lg bg-red-50 border border-red-200 px-3 py-2.5 text-[12.5px] text-red-700">
            {error}
          </div>
        )}

        <button
          type="submit"
          disabled={loading}
          className="w-full h-11 mt-2 rounded-lg bg-gradient-to-b from-gold-500 to-gold-600 hover:from-gold-600 hover:to-gold-700 text-white font-semibold text-[13.5px] inline-flex items-center justify-center gap-2 shadow-[0_4px_14px_rgba(201,162,39,0.3)] hover:shadow-[0_6px_18px_rgba(201,162,39,0.4)] transition disabled:opacity-70"
        >
          {loading ? <Loader2 className="h-4 w-4 animate-spin" /> : (
            <>
              {i18n.t('components.auth.login-form.text_16')}<ArrowLeft className="h-4 w-4" />
            </>
          )}
        </button>

        <button
          type="button"
          onClick={onGoBack}
          disabled={loading}
          className="w-full h-10 mt-1 rounded-lg border border-border hover:bg-muted/50 text-muted-foreground font-medium text-[12.5px] inline-flex items-center justify-center gap-1.5 transition"
        >
          <ArrowRight className="h-3.5 w-3.5" />
          {i18n.t('components.auth.login-form.text_17')}</button>

        <div className="rounded-lg bg-gold-50 border border-gold-200 p-3 mt-4">
          <div className="flex items-start gap-2.5">
            <ShieldCheck className="h-4 w-4 text-gold-700 mt-0.5 shrink-0" />
            <p className="text-[11.5px] leading-relaxed text-gold-900">
              {i18n.t('components.auth.login-form.text_18')}</p>
          </div>
        </div>
      </form>
    )
  }

  return (
    <form className="space-y-4" onSubmit={onSubmitCredentials}>
      <div>
        <label className="block text-[12.5px] font-semibold text-foreground mb-1.5">{i18n.t('components.auth.login-form.text_19')}</label>
        <div className="relative">
          <Mail className="absolute right-3 top-1/2 -translate-y-1/2 h-[17px] w-[17px] text-muted-foreground" />
          <input
            type="email"
            required
            value={username}
            onChange={(e) => setUsername(e.target.value)}
            className="w-full h-11 pr-10 pl-4 rounded-lg border border-border bg-card text-[13.5px] focus:outline-none focus:border-gold-500 focus:ring-2 focus:ring-gold-500/20 transition"
            placeholder="admin@institution.com"
          />
        </div>
      </div>

      <div>
        <div className="flex items-center justify-between mb-1.5">
          <label className="text-[12.5px] font-semibold text-foreground">{i18n.t('components.auth.login-form.text_20')}</label>
          <Link href="#" className="text-[11.5px] font-semibold text-gold-600 hover:text-gold-700">
            {i18n.t('components.auth.login-form.text_21')}</Link>
        </div>
        <div className="relative">
          <Lock className="absolute right-3 top-1/2 -translate-y-1/2 h-[17px] w-[17px] text-muted-foreground" />
          <input
            type={showPassword ? "text" : "password"}
            required
            value={password}
            onChange={(e) => setPassword(e.target.value)}
            className="w-full h-11 pr-10 pl-10 rounded-lg border border-border bg-card text-[13.5px] tracking-widest focus:outline-none focus:border-gold-500 focus:ring-2 focus:ring-gold-500/20 transition"
          />
          <button
            type="button"
            onClick={() => setShowPassword(!showPassword)}
            className="absolute left-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground"
          >
            {showPassword ? <EyeOff className="h-4 w-4" /> : <Eye className="h-4 w-4" />}
          </button>
        </div>
      </div>

      {error && (
        <div className="whitespace-pre-line rounded-lg bg-red-50 border border-red-200 px-3 py-2.5 text-[12.5px] text-red-700">
          {error}
        </div>
      )}

      <div className="flex items-center justify-between pt-1">
        <label className="flex items-center gap-2 text-[12.5px] text-foreground cursor-pointer select-none">
          <input type="checkbox" className="h-4 w-4 rounded border-border accent-gold-500" />
          {i18n.t('components.auth.login-form.text_22')}</label>
      </div>

      <button
        type="submit"
        disabled={loading}
        className="w-full h-11 mt-2 rounded-lg bg-gradient-to-b from-gold-500 to-gold-600 hover:from-gold-600 hover:to-gold-700 text-white font-semibold text-[13.5px] inline-flex items-center justify-center gap-2 shadow-[0_4px_14px_rgba(201,162,39,0.3)] hover:shadow-[0_6px_18px_rgba(201,162,39,0.4)] transition disabled:opacity-70"
      >
        {loading ? <Loader2 className="h-4 w-4 animate-spin" /> : (
          <>
            {i18n.t('components.auth.login-form.text_23')}<ArrowLeft className="h-4 w-4" />
          </>
        )}
      </button>

      <div className="rounded-lg bg-gold-50 border border-gold-200 p-3 mt-4">
        <div className="flex items-start gap-2.5">
          <ShieldCheck className="h-4 w-4 text-gold-700 mt-0.5 shrink-0" />
          <p className="text-[11.5px] leading-relaxed text-gold-900">
            {i18n.t('components.auth.login-form.text_24')}{" "}
            <Link href="/auth/sign-up" className="font-semibold underline">
              {i18n.t('components.auth.login-form.text_25')}</Link>
          </p>
        </div>
      </div>
    </form>
  )
}
