'use client';

import Link from 'next/link';
import { useEffect, useState, useTransition } from 'react';
import { savedStatus, toggleSaved } from '@/app/account/actions';
import { HeartIcon, LayersIcon, UserIcon, XIcon } from './Icons';

type Session = { signedIn: boolean; name?: string };
let sessionPromise: Promise<Session> | null = null;
/** One request per page view, shared by every widget */
function useSession() {
  const [s, setS] = useState<Session | null>(null);
  useEffect(() => {
    sessionPromise ??= fetch('/account/session/', { cache: 'no-store' })
      .then((r) => r.json() as Promise<Session>)
      .catch(() => ({ signedIn: false }));
    let live = true;
    void sessionPromise.then((v) => live && setS(v));
    return () => {
      live = false;
    };
  }, []);
  return s;
}

/** Header link: "Sign in" or the client's name */
export function AccountLink({ className = '' }: { className?: string }) {
  const s = useSession();
  return (
    <Link href={s?.signedIn ? '/account/' : '/account/login/'} className={`inline-flex items-center gap-1.5 rounded-md px-3 py-2 text-sm font-medium text-ink-2 transition-colors hover:bg-sunken hover:text-ink ${className}`}>
      <UserIcon className="h-4 w-4" />
      <span className="max-w-[9rem] truncate">{s?.signedIn ? s.name : 'Sign in'}</span>
    </Link>
  );
}

/** Save a lawyer or firm to the client's account (explains sign-in if needed) */
export function SaveButton({ kind, slug, name }: { kind: 'lawyers' | 'firms'; slug: string; name: string }) {
  const s = useSession();
  const [saved, setSaved] = useState(false);
  const [hint, setHint] = useState('');
  const [pending, start] = useTransition();
  useEffect(() => {
    if (s?.signedIn) void savedStatus(kind, [slug]).then((list) => setSaved(list.includes(slug)));
  }, [s?.signedIn, kind, slug]);
  return (
    <span className="inline-flex flex-col items-start gap-1">
      <button
        type="button"
        disabled={pending}
        aria-pressed={saved}
        onClick={() =>
          start(async () => {
            const r = await toggleSaved(kind, slug, !saved);
            if (r.needLogin) setHint('login');
            else if (r.error) setHint(r.error);
            else {
              setSaved(!!r.saved);
              setHint('');
            }
          })
        }
        className={`btn btn-sm ${saved ? 'btn-primary' : 'btn-quiet'}`}
        aria-label={saved ? `Remove ${name} from saved` : `Save ${name}`}
      >
        <HeartIcon className={`h-4 w-4 ${saved ? 'fill-current' : ''}`} /> {saved ? 'Saved' : 'Save'}
      </button>
      {hint === 'login' ? (
        <span className="text-xs text-muted">
          <Link href={`/account/login/?next=${encodeURIComponent(typeof window === 'undefined' ? '/' : location.pathname)}`} className="link">
            Sign in
          </Link>{' '}
          or{' '}
          <Link href="/account/register/" className="link">
            create a free account
          </Link>{' '}
          to save.
        </span>
      ) : (
        hint && <span className="text-xs text-danger">{hint}</span>
      )}
    </span>
  );
}

// ─────────────────────────── Compare (works without an account; kept in this browser)

const KEY = 'jc_compare';
const MAX = 4;
type Item = { slug: string; name: string };
const read = (): Item[] => {
  try {
    return (JSON.parse(localStorage.getItem(KEY) ?? '[]') as Item[]).slice(0, MAX);
  } catch {
    return [];
  }
};
const write = (items: Item[]) => {
  try {
    localStorage.setItem(KEY, JSON.stringify(items.slice(0, MAX)));
  } catch {
    /* storage blocked */
  }
  window.dispatchEvent(new Event('jc-compare'));
};
export function useCompare() {
  const [items, setItems] = useState<Item[]>([]);
  useEffect(() => {
    const sync = () => setItems(read());
    sync();
    window.addEventListener('jc-compare', sync);
    window.addEventListener('storage', sync);
    return () => {
      window.removeEventListener('jc-compare', sync);
      window.removeEventListener('storage', sync);
    };
  }, []);
  return items;
}

export function CompareToggle({ slug, name }: { slug: string; name: string }) {
  const items = useCompare();
  const on = items.some((i) => i.slug === slug);
  const full = !on && items.length >= MAX;
  return (
    <button
      type="button"
      disabled={full}
      title={full ? `You can compare up to ${MAX} lawyers` : undefined}
      aria-pressed={on}
      onClick={() => write(on ? items.filter((i) => i.slug !== slug) : [...items, { slug, name }])}
      className={`btn btn-sm ${on ? 'btn-primary' : 'btn-quiet'}`}
    >
      <LayersIcon className="h-4 w-4" /> {on ? 'In comparison' : 'Compare'}
    </button>
  );
}

/** Floating tray listing the lawyers picked for comparison */
export function CompareBar() {
  const items = useCompare();
  if (!items.length) return null;
  return (
    <div className="fixed inset-x-0 bottom-0 z-40 border-t border-rule bg-surface/95 shadow-lg backdrop-blur">
      <div className="mx-auto flex max-w-6xl flex-wrap items-center gap-2 px-4 py-2.5 text-sm sm:px-6">
        <LayersIcon className="h-4 w-4 text-ledger" />
        <span className="font-medium">Compare:</span>
        {items.map((i) => (
          <span key={i.slug} className="inline-flex items-center gap-1 rounded-full bg-sunken px-2.5 py-1 text-xs">
            {i.name}
            <button type="button" aria-label={`Remove ${i.name}`} onClick={() => write(items.filter((x) => x.slug !== i.slug))} className="text-muted hover:text-danger">
              <XIcon className="h-3 w-3" />
            </button>
          </span>
        ))}
        <span className="ml-auto flex gap-2">
          <button type="button" className="btn btn-ghost btn-sm" onClick={() => write([])}>
            Clear
          </button>
          <Link href={`/compare/?lawyers=${encodeURIComponent(items.map((i) => i.slug).join(','))}`} className={`btn btn-primary btn-sm ${items.length < 2 ? 'pointer-events-none opacity-50' : ''}`} aria-disabled={items.length < 2}>
            Compare {items.length}
          </Link>
        </span>
      </div>
    </div>
  );
}
