'use client';

import { useEffect, useRef, useState } from 'react';
import { useRouter } from 'next/navigation';
import { captureAuthEpoch, useAuthStore } from '@/stores/auth';
import { api } from '@/lib/api';
import { Button } from '@/components/ui/button';
import { captureInvitation, clearInvitation } from '@/lib/invitation-continuation';

type AcceptedInvitation = { storeId: string; userId: string; sessionToken: string | null; authEpoch: number };

export default function InvitationAcceptPage() {
  const router = useRouter();
  const { user, isLoading, refreshMemberships, selectStore, logout } = useAuthStore();
  const [accepted, setAccepted] = useState<AcceptedInvitation | null>(null);
  const [error, setError] = useState<string | null>(null);
  const [token, setToken] = useState<string | null>(null);
  const [ready, setReady] = useState(false);
  const [busy, setBusy] = useState(false);
  const inFlight = useRef(false);
  const mounted = useRef(false);
  useEffect(() => {
    mounted.current = true;
    try {
      setToken(captureInvitation());
    } catch {
      setError('Please enable session storage in your browser, then reopen the invitation email.');
    }
    setReady(true);
    return () => { mounted.current = false; };
  }, []);

  function cancelInvitation() {
    if (inFlight.current) return;
    clearInvitation();
    setToken(null);
    router.replace('/');
  }

  async function changeAccount() {
    if (inFlight.current) return;
    inFlight.current = true;
    setBusy(true);
    try {
      await logout();
      if (mounted.current) router.replace('/login?next=/invitations/accept');
    } catch {
      setError('Could not sign out. Please try again.');
    } finally {
      inFlight.current = false;
      if (mounted.current) setBusy(false);
    }
  }

  async function acceptInvitation() {
    const account = useAuthStore.getState();
    if ((!token && !accepted) || !account.user || isLoading || inFlight.current) return;
    const userId = account.user.id;
    const sessionToken = account.token;
    const authEpoch = captureAuthEpoch();
    const sameAccount = () => {
      const current = useAuthStore.getState();
      return mounted.current && captureAuthEpoch() === authEpoch && current.user?.id === userId && current.token === sessionToken;
    };
    if (accepted && (accepted.authEpoch !== authEpoch || accepted.userId !== userId || accepted.sessionToken !== sessionToken)) {
      setError('Your account changed. Reopen your invitation email with the invited account.');
      return;
    }
    inFlight.current = true;
    setBusy(true);
    setError(null);
    let storeId = accepted?.storeId;
    try {
      if (!storeId) {
        const response = await api.team.invitations.accept(token!);
        if (!sameAccount()) return;
        storeId = response.data.store_id;
        setAccepted({ storeId, userId, sessionToken, authEpoch });
        clearInvitation();
      }
      await refreshMemberships();
      if (!sameAccount()) return;
      // Acceptance alone is not a new source of authority: read discovery back.
      if (!useAuthStore.getState().memberships?.some(m => m.store_id === storeId)) throw new Error('Membership unavailable');
      selectStore(storeId);
      router.replace('/staff');
    } catch {
      if (!sameAccount()) return;
      setError(storeId
        ? 'Your invitation was accepted, but we could not verify store access. Retry store access without accepting again.'
        : 'Could not accept this invitation. It may be expired, revoked, already used, or intended for a different account. Check your account or ask your manager for help, then try again.');
    } finally {
      inFlight.current = false;
      if (mounted.current) setBusy(false);
    }
  }

  if (!ready || isLoading) return <p role="status">Loading your account…</p>;
  if (!token && !accepted) return <p role="alert">{error ?? 'Your invitation link is missing or invalid. Open the link from your invitation email.'}</p>;
  if (!user) return (
    <div className="space-y-4">
      <h1 className="text-2xl font-bold">Join your store</h1>
      <p>Sign in with the account that received this invitation, or register using the invited email and your phone number.</p>
      <a className="block text-forest-700 underline" href="/login?next=/invitations/accept">Sign in</a>
      <a className="block text-forest-700 underline" href="/register?next=/invitations/accept">Create an account</a>
      <Button variant="ghost" onClick={cancelInvitation}>Cancel invitation</Button>
    </div>
  );

  return (
    <div>
      <h1 className="text-2xl font-bold text-slate-900">Store invitation</h1>
      <p className="mt-3 text-sm text-slate-600">Signed in as {user.email}. Accept only if this is the account invited to your store.</p>
      {error && <p role="alert" className="mt-4 text-sm text-red-700">{error}</p>}
      <Button className="mt-6 w-full" onClick={acceptInvitation} disabled={busy}>
        {busy ? 'Please wait…' : accepted ? 'Retry store access' : 'Accept invitation'}
      </Button>
      {!accepted && <Button className="mt-3 w-full" variant="outline" onClick={changeAccount} disabled={busy}>Use a different account</Button>}
      <Button className="mt-3 w-full" variant="ghost" onClick={cancelInvitation} disabled={busy}>Cancel invitation</Button>
    </div>
  );
}
