<!--
  PIN management for the profile you are signed in as.

  Deliberately scoped to the *active* profile. Letting a signed-in session set a
  PIN on someone else's profile would be an escalation path with no real use —
  a PIN-less profile could be locked by anyone standing at the device, and the
  owner would be pushed down the password route to get back into their own
  account. Other profiles are listed read-only so a parent can see at a glance
  which are protected; adding and removing them lives on the picker.

  Nothing here compares a PIN or counts an attempt. The form validates shape so
  it can say what is wrong before submitting; Rust validates again and is the
  only thing that ever verifies one.

  TRACES: UR-082, UR-083 | DR-268, DR-276
-->
<script lang="ts">
  import { onMount } from "svelte";
  import { goto } from "$app/navigation";
  import { profiles } from "$lib/stores/profiles";
  import {
    validatePinForm,
    pinActionLabel,
    PIN_MAX_LENGTH,
    type PinIntent,
  } from "$lib/utils/pinForm";
  import { createLogger } from "$lib/utils/logger";

  const log = createLogger("ProfileSecurity");

  let intent = $state<PinIntent | null>(null);
  let currentPin = $state("");
  let newPin = $state("");
  let confirmPin = $state("");
  let busy = $state(false);
  let error = $state<string | null>(null);
  let notice = $state<string | null>(null);

  const active = $derived($profiles.profiles.find((p) => p.isActive) ?? null);
  const others = $derived($profiles.profiles.filter((p) => !p.isActive));
  const hasPin = $derived(active?.unlockMethod === "pin");

  const validationError = $derived(
    intent === null ? null : validatePinForm({ intent, hasPin, currentPin, newPin, confirmPin }),
  );

  onMount(() => {
    void profiles.refresh();
  });

  function begin(next: PinIntent) {
    intent = next;
    currentPin = "";
    newPin = "";
    confirmPin = "";
    error = null;
    notice = null;
  }

  function cancel() {
    intent = null;
    currentPin = "";
    newPin = "";
    confirmPin = "";
    error = null;
  }

  async function submit(event: Event) {
    event.preventDefault();
    if (!active || intent === null || validationError) return;

    busy = true;
    error = null;
    try {
      await profiles.setPin(
        active.userId,
        hasPin ? currentPin : null,
        intent === "clear" ? null : newPin,
      );
      notice =
        intent === "clear" ? "PIN turned off. This profile now opens with one tap." : "PIN saved.";
      cancel();
    } catch (e) {
      log.error("Could not update PIN:", e);
      error = e instanceof Error ? e.message : "Could not update the PIN";
    } finally {
      busy = false;
    }
  }
</script>

<div class="space-y-5">
  {#if !active}
    <p class="text-sm text-gray-400">No profile is signed in.</p>
  {:else}
    <div class="flex items-start justify-between gap-4">
      <div>
        <h3 class="text-lg font-semibold text-white mb-1">
          PIN for {active.username}
        </h3>
        <p class="text-sm text-gray-400">
          {#if hasPin}
            This profile asks for a PIN before anyone can switch to it.
          {:else}
            This profile opens with one tap — right for a child's account, and what you want unless
            there is something to keep out.
          {/if}
        </p>
      </div>
      <span
        class="shrink-0 text-xs px-2 py-1 rounded-full {hasPin
          ? 'bg-green-900/60 text-green-300'
          : 'bg-gray-700 text-gray-300'}"
      >
        {hasPin ? "On" : "Off"}
      </span>
    </div>

    {#if notice}
      <p class="text-sm text-green-400">{notice}</p>
    {/if}

    {#if intent === null}
      <div class="flex flex-wrap gap-3">
        {#if hasPin}
          <button
            onclick={() => begin("change")}
            class="px-4 py-2 bg-[var(--color-jellyfin)] hover:bg-[var(--color-jellyfin-dark)] rounded-lg font-medium transition-colors"
          >
            Change PIN
          </button>
          <button
            onclick={() => begin("clear")}
            class="px-4 py-2 border border-gray-600 hover:bg-gray-700 rounded-lg transition-colors"
          >
            Turn off PIN
          </button>
        {:else}
          <button
            onclick={() => begin("set")}
            class="px-4 py-2 bg-[var(--color-jellyfin)] hover:bg-[var(--color-jellyfin-dark)] rounded-lg font-medium transition-colors"
          >
            Set a PIN
          </button>
        {/if}
      </div>
    {:else}
      <form onsubmit={submit} class="space-y-4 max-w-sm">
        {#if hasPin}
          <div>
            <label for="current-pin" class="block text-sm font-medium text-gray-300 mb-2">
              Current PIN
            </label>
            <input
              id="current-pin"
              type="password"
              inputmode="numeric"
              maxlength={PIN_MAX_LENGTH}
              bind:value={currentPin}
              disabled={busy}
              class="w-full px-4 py-3 bg-[var(--color-bg)] border border-gray-700 rounded-lg focus:outline-none focus:border-[var(--color-jellyfin)] text-white tracking-widest"
            />
          </div>
        {/if}

        {#if intent !== "clear"}
          <div>
            <label for="new-pin" class="block text-sm font-medium text-gray-300 mb-2">
              New PIN (4–8 digits)
            </label>
            <input
              id="new-pin"
              type="password"
              inputmode="numeric"
              maxlength={PIN_MAX_LENGTH}
              bind:value={newPin}
              disabled={busy}
              class="w-full px-4 py-3 bg-[var(--color-bg)] border border-gray-700 rounded-lg focus:outline-none focus:border-[var(--color-jellyfin)] text-white tracking-widest"
            />
          </div>
          <div>
            <label for="confirm-pin" class="block text-sm font-medium text-gray-300 mb-2">
              Confirm new PIN
            </label>
            <input
              id="confirm-pin"
              type="password"
              inputmode="numeric"
              maxlength={PIN_MAX_LENGTH}
              bind:value={confirmPin}
              disabled={busy}
              class="w-full px-4 py-3 bg-[var(--color-bg)] border border-gray-700 rounded-lg focus:outline-none focus:border-[var(--color-jellyfin)] text-white tracking-widest"
            />
          </div>
        {:else}
          <p class="text-sm text-gray-400">
            Turning the PIN off means anyone using this device can switch to
            {active.username} in one tap.
          </p>
        {/if}

        {#if error}
          <div class="p-3 bg-red-900/50 border border-red-700 rounded-lg text-red-200 text-sm">
            {error}
          </div>
        {:else if validationError && (currentPin || newPin || confirmPin)}
          <p class="text-sm text-amber-400">{validationError}</p>
        {/if}

        <div class="flex gap-3">
          <button
            type="button"
            onclick={cancel}
            disabled={busy}
            class="flex-1 py-3 rounded-lg border border-gray-600 hover:bg-gray-700 transition-colors"
          >
            Cancel
          </button>
          <button
            type="submit"
            disabled={busy || validationError !== null}
            class="flex-1 py-3 rounded-lg bg-[var(--color-jellyfin)] hover:bg-[var(--color-jellyfin-dark)] disabled:opacity-50 disabled:cursor-not-allowed font-medium transition-colors"
          >
            {pinActionLabel(intent)}
          </button>
        </div>
      </form>
    {/if}

    {#if others.length > 0}
      <div class="border-t border-gray-700 pt-5">
        <h3 class="text-sm font-semibold text-white mb-3">Other profiles on this device</h3>
        <ul class="space-y-2">
          {#each others as profile (profile.userId)}
            <li class="flex items-center justify-between text-sm">
              <span class="text-gray-300">{profile.username}</span>
              <span class="text-xs text-gray-500">
                {profile.unlockMethod === "pin" ? "PIN" : "No PIN"}
              </span>
            </li>
          {/each}
        </ul>
        <p class="text-xs text-gray-500 mt-3">
          A profile's PIN can only be changed from that profile. Sign in as them to set one.
        </p>
      </div>
    {/if}

    <div class="border-t border-gray-700 pt-5">
      <button
        onclick={() => goto("/profiles?manage=1")}
        class="text-sm text-[var(--color-jellyfin)] hover:underline"
      >
        Add or remove profiles
      </button>
    </div>
  {/if}
</div>
