import { createFileRoute } from "@tanstack/react-router";
import { useEffect, useState, useCallback } from "react";
import { ToolShell } from "@/components/ToolShell";
import { Button } from "@/components/ui/button";
import { Checkbox } from "@/components/ui/checkbox";
import { Slider } from "@/components/ui/slider";
import { RefreshCw, Copy } from "lucide-react";

export const Route = createFileRoute("/tools/password-generator")({
  head: () => ({
    meta: [
      { title: "Password Generator — Toolkit" },
      {
        name: "description",
        content:
          "Generate strong, customizable passwords locally using your browser's crypto API.",
      },
      { property: "og:title", content: "Password Generator — Toolkit" },
      {
        property: "og:description",
        content: "Strong, customizable passwords generated locally.",
      },
    ],
  }),
  component: PasswordGen,
});

const SETS = {
  lower: "abcdefghijklmnopqrstuvwxyz",
  upper: "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
  digits: "0123456789",
  symbols: "!@#$%^&*()-_=+[]{};:,.?/",
};

function PasswordGen() {
  const [length, setLength] = useState(20);
  const [opts, setOpts] = useState({ lower: true, upper: true, digits: true, symbols: true });
  const [pw, setPw] = useState("");

  const generate = useCallback(() => {
    const pool = (Object.keys(SETS) as (keyof typeof SETS)[])
      .filter((k) => opts[k])
      .map((k) => SETS[k])
      .join("");
    if (!pool) {
      setPw("");
      return;
    }
    const arr = new Uint32Array(length);
    crypto.getRandomValues(arr);
    let out = "";
    for (let i = 0; i < length; i++) out += pool[arr[i] % pool.length];
    setPw(out);
  }, [length, opts]);

  useEffect(() => {
    generate();
  }, [generate]);

  const strength = Math.min(100, Math.round((length * Object.values(opts).filter(Boolean).length * 100) / 40));

  return (
    <ToolShell
      title="Password Generator"
      description="Cryptographically random passwords generated entirely in your browser."
    >
      <div className="rounded-2xl border border-border/80 bg-card p-6 shadow-[var(--shadow-soft)]">
        <div className="flex items-center gap-2 rounded-xl border border-border/80 bg-muted/40 p-3">
          <code className="flex-1 truncate font-mono text-base sm:text-lg">{pw || "—"}</code>
          <Button size="icon" variant="ghost" onClick={generate} aria-label="Regenerate">
            <RefreshCw className="h-4 w-4" />
          </Button>
          <Button
            size="icon"
            variant="ghost"
            onClick={() => pw && navigator.clipboard.writeText(pw)}
            aria-label="Copy"
          >
            <Copy className="h-4 w-4" />
          </Button>
        </div>

        <div className="mt-3 h-1.5 w-full overflow-hidden rounded-full bg-muted">
          <div
            className="h-full transition-all"
            style={{
              width: `${strength}%`,
              background: "var(--gradient-primary)",
            }}
          />
        </div>

        <div className="mt-8 space-y-6">
          <div>
            <div className="mb-2 flex items-center justify-between text-sm">
              <span className="font-medium">Length</span>
              <span className="font-mono text-muted-foreground">{length}</span>
            </div>
            <Slider
              value={[length]}
              min={6}
              max={64}
              step={1}
              onValueChange={(v) => setLength(v[0])}
            />
          </div>

          <div className="grid grid-cols-2 gap-3 sm:grid-cols-4">
            {(Object.keys(SETS) as (keyof typeof SETS)[]).map((k) => (
              <label
                key={k}
                className="flex cursor-pointer items-center gap-2 rounded-xl border border-border/80 bg-background p-3 transition-colors hover:bg-accent/50"
              >
                <Checkbox
                  checked={opts[k]}
                  onCheckedChange={(v) => setOpts({ ...opts, [k]: !!v })}
                />
                <span className="text-sm capitalize">{k}</span>
              </label>
            ))}
          </div>
        </div>
      </div>
    </ToolShell>
  );
}
