import { FormEvent, useEffect, useMemo, useState } from 'react';
import { Loader2, LockKeyhole, RefreshCw } from 'lucide-react';
import { useNavigate } from 'react-router-dom';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { useYinianStore } from '@/stores/yinian';
import { YinianPanel, yinianPrimaryButton } from '@/components/yinian/ui';
import logoSvg from '@/assets/logo.svg';
import type { YinianImageCaptcha } from '../../../shared/yinian';
import type { YinianServerStatus } from '../../../shared/yinian';
import { useTranslation } from 'react-i18next';

export function YinianLogin() {
  const navigate = useNavigate();
  const { t } = useTranslation('setup');
  const status = useYinianStore((state) => state.status);
  const error = useYinianStore((state) => state.error);
  const loginWithPassword = useYinianStore((state) => state.loginWithPassword);

  const [account, setAccount] = useState('');
  const [password, setPassword] = useState('');
  const [rememberPassword, setRememberPassword] = useState(false);
  const [captchaCode, setCaptchaCode] = useState('');
  const [captcha, setCaptcha] = useState<YinianImageCaptcha | null>(null);
  const [captchaLoading, setCaptchaLoading] = useState(false);
  const [serverStatus, setServerStatus] = useState<YinianServerStatus | null>(null);
  const isLoading = status === 'loading';
  const serverConfigured = Boolean(serverStatus?.apiBaseUrl) || serverStatus?.mode === 'mock';
  const captchaSrc = useMemo(() => {
    if (!captcha) return '';
    if (captcha.image?.startsWith('data:')) return captcha.image;
    if (captcha.image) return captcha.image;
    if (captcha.imageBase64) {
      return `data:${captcha.mimeType || 'image/png'};base64,${captcha.imageBase64}`;
    }
    return '';
  }, [captcha]);
  const captchaRequired = Boolean(captchaSrc);

  const refreshCaptcha = async () => {
    setCaptchaLoading(true);
    try {
      const randomStr = crypto.randomUUID();
      const next = await window.yinian.auth.createImageCaptcha(randomStr);
      setCaptcha(next);
      setCaptchaCode('');
    } catch {
      setCaptcha(null);
    } finally {
      setCaptchaLoading(false);
    }
  };

  useEffect(() => {
    void window.yinian.app.getServerStatus()
      .then(setServerStatus)
      .catch(() => setServerStatus(null));
    void refreshCaptcha();
    void window.yinian.auth.getSavedCredentials()
      .then((credentials) => {
        if (!credentials) return;
        setAccount(credentials.account);
        setPassword(credentials.password ?? '');
        setRememberPassword(credentials.rememberPassword);
      })
      .catch(() => undefined);
  }, []);

  const handlePasswordLogin = async (event: FormEvent) => {
    event.preventDefault();
    await loginWithPassword({
      account: account.trim(),
      password,
      captchaCode: captchaCode.trim(),
      randomStr: captcha?.randomStr,
    });
    if (rememberPassword) {
      void window.yinian.auth.saveCredentials({
        account: account.trim(),
        password,
        rememberPassword: true,
      }).catch(() => undefined);
    } else {
      void window.yinian.auth.clearSavedCredentials().catch(() => undefined);
    }
    navigate('/', { replace: true });
  };

  return (
    <div data-testid="yinian-login-page" className="yinian-app-surface flex min-h-screen text-slate-950 dark:bg-slate-950 dark:text-slate-50">
      <section className="yinian-visual-band hidden w-[44%] min-w-[460px] flex-col items-center justify-center border-r border-[#D5E8F3]/75 px-12 py-10 text-slate-950 lg:flex">
        <div className="flex flex-col items-center gap-6 text-center">
          <span className="flex h-24 w-24 items-center justify-center rounded-lg bg-white/70 ring-1 ring-[#D5E8F3]">
            <img src={logoSvg} alt={t('login.appName')} className="h-20 w-20 rounded-3xl" />
          </span>
          <h1 className="text-3xl font-semibold tracking-normal">{t('login.slogan')}</h1>
        </div>
      </section>

      <main className="flex flex-1 items-center justify-center px-6 py-10">
        <YinianPanel className="w-full max-w-[430px]">
          <div className="p-6 pb-0">
            <div className="mb-3 flex items-center gap-2 lg:hidden">
              <img src={logoSvg} alt={t('login.appName')} className="h-9 w-9 rounded-xl" />
              <span className="text-base font-semibold">{t('login.appName')}</span>
            </div>
            <h1 className="text-2xl font-semibold tracking-normal">{t('login.title')}</h1>
            <p className="mt-1.5 text-sm text-muted-foreground">{t('login.slogan')}</p>
            {serverStatus && (
              <div className={`mt-4 rounded-lg border px-3 py-2 text-xs ${
                serverConfigured
                  ? 'border-emerald-200 bg-emerald-50 text-emerald-700 dark:border-emerald-900/60 dark:bg-emerald-950/30 dark:text-emerald-200'
                  : 'border-amber-200 bg-amber-50 text-amber-800 dark:border-amber-900/60 dark:bg-amber-950/30 dark:text-amber-200'
              }`}
              >
                {serverConfigured
                  ? t('login.serverEnabled', { baseUrl: serverStatus.apiBaseUrl ? `: ${serverStatus.apiBaseUrl}` : '' })
                  : serverStatus.message}
              </div>
            )}
          </div>
          <div className="p-6">
            <form className="space-y-4" onSubmit={handlePasswordLogin}>
              <div className="space-y-2">
                <Label htmlFor="account">{t('login.account')}</Label>
                <Input
                  id="account"
                  value={account}
                  onChange={(event) => setAccount(event.target.value)}
                  placeholder={t('login.accountPlaceholder')}
                  autoComplete="username"
                />
              </div>
              <div className="space-y-2">
                <Label htmlFor="password">{t('login.password')}</Label>
                <Input
                  id="password"
                  type="password"
                  value={password}
                  onChange={(event) => setPassword(event.target.value)}
                  placeholder={t('login.passwordPlaceholder')}
                  autoComplete="current-password"
                />
              </div>
              <CaptchaField
                value={captchaCode}
                onChange={setCaptchaCode}
                imageSrc={captchaSrc}
                loading={captchaLoading}
                onRefresh={refreshCaptcha}
                label={t('login.captcha')}
                placeholder={t('login.captchaPlaceholder')}
                refreshTitle={t('login.refreshCaptcha')}
              />
              <label className="flex items-center gap-2 text-sm text-muted-foreground">
                <input
                  type="checkbox"
                  checked={rememberPassword}
                  onChange={(event) => setRememberPassword(event.target.checked)}
                  className="h-4 w-4 rounded border-slate-300"
                />
                {t('login.rememberPassword')}
              </label>
              {error && <p className="text-sm text-destructive">{error}</p>}
              <Button type="submit" className={`w-full ${yinianPrimaryButton}`} disabled={isLoading || !serverConfigured || (captchaRequired && !captchaCode.trim())}>
                {isLoading ? <Loader2 className="mr-2 h-4 w-4 animate-spin" /> : <LockKeyhole className="mr-2 h-4 w-4" />}
                {t('login.submit')}
              </Button>
            </form>
          </div>
        </YinianPanel>
      </main>
    </div>
  );
}

function CaptchaField({
  value,
  onChange,
  imageSrc,
  loading,
  onRefresh,
  label,
  placeholder,
  refreshTitle,
}: {
  value: string;
  onChange: (value: string) => void;
  imageSrc: string;
  loading: boolean;
  onRefresh: () => void | Promise<void>;
  label: string;
  placeholder: string;
  refreshTitle: string;
}) {
  if (!imageSrc) return null;

  return (
    <div className="space-y-2">
      <Label htmlFor="captcha-code">{label}</Label>
      <div className="flex gap-2">
        <Input
          id="captcha-code"
          value={value}
          onChange={(event) => onChange(event.target.value)}
          placeholder={placeholder}
        />
        <button
          type="button"
          onClick={() => void onRefresh()}
          className="flex h-10 w-28 shrink-0 items-center justify-center overflow-hidden rounded-md border border-slate-200 bg-white text-xs text-muted-foreground transition-colors hover:bg-slate-50 dark:border-white/10 dark:bg-slate-900 dark:hover:bg-white/5"
          title={refreshTitle}
        >
          {loading ? (
            <RefreshCw className="h-4 w-4 animate-spin" />
          ) : (
            <img src={imageSrc} alt={label} className="h-full w-full object-contain" />
          )}
        </button>
      </div>
    </div>
  );
}

export default YinianLogin;
