'use client';

import {useState} from 'react';
import {LOGIN_ENDPOINT, useLoginForm} from '@/features/auth/hooks/useLoginForm';
import {GoogleIcon, MicrosoftIcon} from './ProviderIcons';

/**
 * The sign-in form itself: two fields, the remember-me control, the submit
 * button and the federated options.
 *
 * All state and every rule come from useLoginForm — this file decides only how
 * things look. That separation is what lets the error copy, the redirect
 * target and the validation change without touching markup, and vice versa.
 *
 * ── On the hand-rolled Tailwind here ─────────────────────────────────────
 * The rest of the app is built from Astryx components, and this screen
 * deliberately is not: it predates the workspace, it is the only page a
 * merchant sees before the product, and it was signed off looking like this.
 * The brief says preserve the existing UI, so the markup is unchanged —
 * what changed is that the button beneath it now talks to a real endpoint.
 */
export function LoginCredentialsForm() {
  const [showPassword, setShowPassword] = useState(false);
  const {
    email,
    password,
    rememberMe,
    errors,
    isSubmitting,
    next,
    setEmail,
    setPassword,
    setRememberMe,
    submit,
  } = useLoginForm();

  return (
    /**
     * `method="post"` and `action` are the no-JavaScript safety net, and they
     * are load-bearing rather than decorative.
     *
     * `submit` calls preventDefault, so on a hydrated page these attributes
     * are never exercised. But hydration is not instantaneous: a form with
     * neither attribute submits GET to its own URL, so a Continue pressed
     * before React attached — or on a page whose bundle failed outright —
     * navigated to `/login?email=…&password=…`, writing the password into the
     * address bar, the history and every log along the way.
     *
     * With these set, that same early submit is an ordinary POST with the
     * credentials in the body, and the endpoint answers it with a redirect.
     * Sign-in therefore works with JavaScript disabled entirely.
     */
    <form
      onSubmit={submit}
      method="post"
      action={LOGIN_ENDPOINT}
      noValidate
      className="space-y-4"
    >
      {/*
        The deep link the proxy preserved, carried through the native path —
        the hydrated path reads it from the URL instead. Without it, a no-JS
        sign-in from /login?next=/settings/billing would land on the dashboard.
      */}
      {next && <input type="hidden" name="next" value={next} />}

      <div>
        <label
          htmlFor="login-email"
          className="block text-xs font-medium text-neutral-300 mb-1.5"
        >
          Email address
        </label>
        <input
          id="login-email"
          name="email"
          type="email"
          autoComplete="email"
          value={email}
          onChange={(e) => setEmail(e.target.value)}
          placeholder="name@company.com"
          // aria-invalid + aria-describedby so the message is announced, not
          // just coloured — a red border alone tells a screen reader nothing.
          aria-invalid={!!errors.email || !!errors.form}
          aria-describedby={errors.email ? 'login-email-error' : undefined}
          disabled={isSubmitting}
          className={`w-full h-11 px-3.5 rounded-xl bg-white/[0.04] border ${
            errors.email || errors.form ? 'border-red-500/80' : 'border-white/10'
          } text-white text-sm placeholder:text-neutral-500 focus:outline-none focus:border-white/30 focus:ring-1 focus:ring-white/20 transition-all disabled:opacity-60`}
        />
        {errors.email && (
          <p id="login-email-error" className="text-xs text-red-400 mt-1">
            {errors.email}
          </p>
        )}
      </div>

      <div>
        <label
          htmlFor="login-password"
          className="block text-xs font-medium text-neutral-300 mb-1.5"
        >
          Password
        </label>
        <div className="relative">
          <input
            id="login-password"
            name="password"
            type={showPassword ? 'text' : 'password'}
            autoComplete="current-password"
            value={password}
            onChange={(e) => setPassword(e.target.value)}
            placeholder="Enter your password"
            aria-invalid={!!errors.password || !!errors.form}
            aria-describedby={
              errors.password ? 'login-password-error' : undefined
            }
            disabled={isSubmitting}
            className={`w-full h-11 pl-3.5 pr-10 rounded-xl bg-white/[0.04] border ${
              errors.password || errors.form ? 'border-red-500/80' : 'border-white/10'
            } text-white text-sm placeholder:text-neutral-500 focus:outline-none focus:border-white/30 focus:ring-1 focus:ring-white/20 transition-all disabled:opacity-60`}
          />
          <button
            type="button"
            onClick={() => setShowPassword((prev) => !prev)}
            disabled={isSubmitting}
            aria-label={showPassword ? 'Hide password' : 'Show password'}
            className="absolute right-3 top-1/2 -translate-y-1/2 p-1 text-neutral-400 hover:text-white transition-colors focus:outline-none focus:text-white disabled:opacity-50"
          >
            {showPassword ? (
              <svg
                width="16"
                height="16"
                viewBox="0 0 24 24"
                fill="none"
                stroke="currentColor"
                strokeWidth="2"
                strokeLinecap="round"
                strokeLinejoin="round"
                aria-hidden="true"
              >
                <path d="M9.88 9.88a3 3 0 1 0 4.24 4.24" />
                <path d="M10.73 5.08A10.43 10.43 0 0 1 12 5c7 0 10 7 10 7a13.16 13.16 0 0 1-1.67 2.68" />
                <path d="M6.61 6.61A13.52 13.52 0 0 0 2 12s3 7 10 7a9.74 9.74 0 0 0 5.39-1.61" />
                <line x1="2" x2="22" y1="2" y2="22" />
              </svg>
            ) : (
              <svg
                width="16"
                height="16"
                viewBox="0 0 24 24"
                fill="none"
                stroke="currentColor"
                strokeWidth="2"
                strokeLinecap="round"
                strokeLinejoin="round"
                aria-hidden="true"
              >
                <path d="M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7z" />
                <circle cx="12" cy="12" r="3" />
              </svg>
            )}
          </button>
        </div>
        {errors.password && (
          <p id="login-password-error" className="text-xs text-red-400 mt-1">
            {errors.password}
          </p>
        )}
      </div>

      {/* Anything the server could not attribute to a field — network, 5xx. */}
      {errors.form && (
        <p role="alert" className="text-xs text-red-400">
          {errors.form}
        </p>
      )}

      <div className="flex items-center justify-between pt-1">
        <label className="flex items-center gap-2 cursor-pointer group">
          <input
            type="checkbox"
            name="rememberMe"
            checked={rememberMe}
            onChange={(e) => setRememberMe(e.target.checked)}
            className="w-4 h-4 rounded border-white/20 bg-white/5 text-white focus:ring-0 focus:ring-offset-0 cursor-pointer accent-white"
          />
          <span className="text-xs text-neutral-300 group-hover:text-white transition-colors">
            Remember me
          </span>
        </label>

        <a
          href="#"
          className="text-xs text-neutral-400 hover:text-white transition-colors font-medium"
        >
          Forgot password?
        </a>
      </div>

      <button
        type="submit"
        disabled={isSubmitting}
        className="w-full h-11 mt-2 rounded-xl bg-white text-black font-semibold text-sm hover:bg-neutral-200 active:scale-[0.99] transition-all shadow-md shadow-white/5 flex items-center justify-center gap-2 disabled:opacity-70 disabled:cursor-not-allowed"
      >
        {isSubmitting ? (
          <>
            <span className="inline-block w-4 h-4 border-2 border-black/30 border-t-black rounded-full animate-spin" />
            <span className="sr-only">Signing in</span>
          </>
        ) : (
          <>
            Continue
            <svg
              width="14"
              height="14"
              viewBox="0 0 24 24"
              fill="none"
              stroke="currentColor"
              strokeWidth="2.5"
              aria-hidden="true"
            >
              <path d="M5 12h14M12 5l7 7-7 7" />
            </svg>
          </>
        )}
      </button>

      <div className="relative my-5 text-center">
        <div className="absolute inset-0 flex items-center">
          <div className="w-full border-t border-white/[0.08]" />
        </div>
        <span className="relative px-3 text-xs text-neutral-500 bg-[#14151B]">
          or continue with
        </span>
      </div>

      {/*
        Federated sign-in is not wired up — there is no OAuth client yet, and a
        button that silently does nothing is worse than one that says so. They
        stay disabled and labelled until /api/auth/oauth/:provider exists.
      */}
      <div className="grid grid-cols-2 gap-3">
        <button
          type="button"
          disabled
          title="Google sign-in is not configured yet"
          className="h-11 rounded-xl bg-white/[0.04] border border-white/10 text-white text-xs font-medium transition-all flex items-center justify-center gap-2.5 opacity-50 cursor-not-allowed"
        >
          <GoogleIcon />
          Google
        </button>
        <button
          type="button"
          disabled
          title="Microsoft sign-in is not configured yet"
          className="h-11 rounded-xl bg-white/[0.04] border border-white/10 text-white text-xs font-medium transition-all flex items-center justify-center gap-2.5 opacity-50 cursor-not-allowed"
        >
          <MicrosoftIcon />
          Microsoft
        </button>
      </div>
    </form>
  );
}
