<script lang="ts">
  import { Button } from '@hister/components/ui/button';
  import { Input } from '@hister/components/ui/input';
  import * as Card from '@hister/components/ui/card';
  import { Lock } from '@lucide/svelte';
  import { login, resetConfig } from '$lib/api';

  let authMode = $state<'token' | 'user' | 'none'>('token');
  let token = $state('');
  let username = $state('');
  let password = $state('');
  let error = $state('');
  let loading = $state(false);
  let oauthProviders = $state<string[]>([]);
  let oauthOnly = $state(false);
  let basePath = $state('');

  // Detect auth mode from config endpoint (no credentials required)
  $effect(() => {
    fetch('api/config', { credentials: 'include' })
      .then((r) => r.json())
      .then((cfg) => {
        authMode = cfg.authMode ?? 'token';
        oauthProviders = cfg.oauthProviders ?? [];
        oauthOnly = cfg.oauthOnly ?? false;
        basePath = cfg.basePath ?? '';
        if (authMode === 'none' || cfg.authenticated) {
          window.location.href = '/';
        }
      })
      .catch(() => {});
  });

  function handleTokenSave() {
    localStorage.setItem('access-token', token);
    window.location.href = '/';
  }

  async function handleLogin() {
    error = '';
    loading = true;
    try {
      await login(username, password);
      resetConfig();
      window.location.href = '/';
    } catch {
      error = 'Invalid username or password';
    } finally {
      loading = false;
    }
  }

  function handleKeydown(e: KeyboardEvent) {
    if (e.key === 'Enter') {
      if (authMode === 'user') {
        handleLogin();
      } else {
        handleTokenSave();
      }
    }
  }

  function oauthLogin(provider: string) {
    window.location.href = basePath + '/api/oauth?provider=' + provider;
  }

  const providerLabels: Record<string, string> = {
    github: 'GitHub',
    google: 'Google',
    oidc: 'SSO',
  };
</script>

<svelte:head>
  <title>Authentication - Hister</title>
</svelte:head>

<div class="bg-brutal-bg h-full overflow-y-auto">
  <div class="flex min-h-full items-center justify-center p-4">
    <Card.Root class="w-full max-w-md shadow-[8px_8px_0px_var(--hister-indigo)]">
      <Card.Header
        class="border-border-brand-muted flex-col space-y-4 border-b-[3px] pb-6 text-center"
      >
        <div class="flex justify-center">
          <div
            class="flex size-16 items-center justify-center rounded-full border-[3px]"
            style="background-color: color-mix(in srgb, var(--hister-indigo) 10%, transparent); border-color: var(--hister-indigo);"
          >
            <Lock class="text-hister-indigo size-8" />
          </div>
        </div>
        <Card.Title
          class="font-outfit text-text-brand text-2xl font-extrabold tracking-wide uppercase"
        >
          Authentication Required
        </Card.Title>
        <Card.Description class="font-inter text-text-brand-secondary">
          {#if authMode === 'user'}
            Please sign in.
          {:else}
            Please enter your access token.
          {/if}
        </Card.Description>
      </Card.Header>
      <Card.Content class="space-y-6">
        {#if error}
          <p class="text-hister-rose font-inter text-sm">{error}</p>
        {/if}
        {#if authMode === 'user'}
          {#if !oauthOnly}
            <div class="space-y-2">
              <label
                for="username"
                class="font-space text-text-brand text-sm font-semibold tracking-wider uppercase"
              >
                Username
              </label>
              <Input
                id="username"
                type="text"
                variant="brutal"
                bind:value={username}
                onkeydown={handleKeydown}
                placeholder="Enter your username"
                class="focus-visible:border-hister-indigo"
                autofocus
              />
            </div>
            <div class="space-y-2">
              <label
                for="password"
                class="font-space text-text-brand text-sm font-semibold tracking-wider uppercase"
              >
                Password
              </label>
              <Input
                id="password"
                type="password"
                variant="brutal"
                bind:value={password}
                onkeydown={handleKeydown}
                placeholder="Enter your password"
                class="focus-visible:border-hister-indigo font-mono"
              />
            </div>
            <Button
              onclick={handleLogin}
              disabled={!username.trim() || !password.trim() || loading}
              class="bg-hister-indigo hover:bg-hister-indigo/90 border-brutal-border font-space h-12 w-full rounded-none border-[3px] font-bold tracking-wider uppercase shadow-[4px_4px_0px_var(--brutal-shadow)] transition-all hover:translate-x-0.5 hover:translate-y-0.5 hover:shadow-[2px_2px_0px_var(--brutal-shadow)] active:translate-x-1 active:translate-y-1 active:shadow-none disabled:cursor-not-allowed disabled:opacity-50"
            >
              {loading ? 'Signing in…' : 'Sign In'}
            </Button>
          {/if}
          {#if oauthProviders.length > 0}
            {#if !oauthOnly}
              <div class="relative flex items-center py-2">
                <div class="border-border-brand-muted flex-grow border-t"></div>
                <span class="text-text-brand-muted font-inter mx-3 flex-shrink text-xs uppercase"
                  >or</span
                >
                <div class="border-border-brand-muted flex-grow border-t"></div>
              </div>
            {/if}
            <div class="space-y-2">
              {#each oauthProviders as provider}
                <Button
                  onclick={() => oauthLogin(provider)}
                  variant="outline"
                  class="border-brutal-border font-space h-11 w-full rounded-none border-[3px] font-bold tracking-wider uppercase shadow-[4px_4px_0px_var(--brutal-shadow)] transition-all hover:translate-x-0.5 hover:translate-y-0.5 hover:shadow-[2px_2px_0px_var(--brutal-shadow)] active:translate-x-1 active:translate-y-1 active:shadow-none"
                >
                  Sign in with {providerLabels[provider] ?? provider}
                </Button>
              {/each}
            </div>
          {/if}
        {:else}
          <div class="space-y-2">
            <label
              for="token"
              class="font-space text-text-brand text-sm font-semibold tracking-wider uppercase"
            >
              Token
            </label>
            <Input
              id="token"
              type="password"
              variant="brutal"
              bind:value={token}
              onkeydown={handleKeydown}
              placeholder="Enter your token"
              class="focus-visible:border-hister-indigo font-mono"
              autofocus
            />
          </div>
          <Button
            onclick={handleTokenSave}
            disabled={!token.trim()}
            class="bg-hister-indigo hover:bg-hister-indigo/90 border-brutal-border font-space h-12 w-full rounded-none border-[3px] font-bold tracking-wider uppercase shadow-[4px_4px_0px_var(--brutal-shadow)] transition-all hover:translate-x-0.5 hover:translate-y-0.5 hover:shadow-[2px_2px_0px_var(--brutal-shadow)] active:translate-x-1 active:translate-y-1 active:shadow-none disabled:cursor-not-allowed disabled:opacity-50"
          >
            Save Token
          </Button>
        {/if}
      </Card.Content>
      <Card.Footer class="bg-muted-surface/50">
        <p class="text-text-brand-muted font-inter w-full text-center text-xs">
          {#if oauthOnly || authMode === 'user'}
            Your session will be stored as a secure cookie.
          {:else}
            Your token will be stored locally and used for API requests.
          {/if}
        </p>
      </Card.Footer>
    </Card.Root>
  </div>
</div>
