import { createFileRoute, useNavigate } from '@tanstack/react-router';
import { z } from 'zod';
import { useEffect } from 'react';
import { Currency, isCurrency } from '@archer/domain';
import { tokenStorage } from '@/infrastructure/storage/LocalTokenStorage';
import { authenticatedUserStore } from '@/infrastructure/storage/AuthenticatedUserStore';
import { AuthenticatedUserMapper } from '@/infrastructure/http/api/auth/mappers/AuthenticatedUserMapper';
import type { AuthenticatedAccount } from '@/domain/entities/AuthenticatedUser';
import { decodeJwt } from '@/lib/jwt';
import { base64ToUtf8 } from '@/lib/base64';

const callbackSearchSchema = z.object({
  token: z.string(),
  refresh: z.string(),
});

export const Route = createFileRoute('/auth/callback')({
  validateSearch: callbackSearchSchema,
  component: AuthCallbackPage,
});

/**
 * Pull the `account` slice out of the URL fragment (#account=<base64>) and
 * decode it. Landing-web passes it this way so the dashboard has authoritative
 * isProfileComplete + emailVerified + preferredCurrency from first render,
 * instead of defaulting to false/USD until /auth/me catches up.
 *
 * Fragment (not query) keeps the payload out of server logs and Referer.
 */
function readAccountFragment(): AuthenticatedAccount | null {
  if (typeof window === 'undefined') return null;
  const hash = window.location.hash.replace(/^#/, '');
  if (!hash) return null;
  const raw = new URLSearchParams(hash).get('account');
  if (!raw) return null;
  try {
    const decoded = JSON.parse(base64ToUtf8(decodeURIComponent(raw))) as Partial<AuthenticatedAccount>;
    const currencyCandidate = (decoded as AuthenticatedAccount).preferredCurrency;
    return {
      preferredCurrency: isCurrency(currencyCandidate) ? currencyCandidate : Currency.USD,
      isProfileComplete: Boolean(decoded.isProfileComplete),
      missingProfileFields: Array.isArray(decoded.missingProfileFields) ? decoded.missingProfileFields : [],
      emailVerified: Boolean(decoded.emailVerified),
    };
  } catch {
    return null;
  }
}

function AuthCallbackPage() {
  const { token, refresh } = Route.useSearch();
  const navigate = useNavigate();

  useEffect(() => {
    // Store tokens
    tokenStorage.setTokens(token, refresh);

    const payload = decodeJwt(token);
    const accountFromFragment = readAccountFragment();

    if (payload) {
      try {
        // JWT gives us identity + company context; the URL fragment gives us
        // billing-state flags landing-web already fetched from /auth/login.
        // Merge them so gate-time reads of authed.account are correct.
        const baseUser = AuthenticatedUserMapper.fromJwtPayload(payload);
        authenticatedUserStore.set(
          accountFromFragment ? baseUser.with({ account: accountFromFragment }) : baseUser,
        );
      } catch {
        /* missing currentCompanyId — guard will bounce to /login */
      }
    }

    // Replace URL to remove tokens + account fragment from history
    window.history.replaceState({}, '', '/auth/callback');

    // Navigate to dashboard
    navigate({ to: '/dashboard' });
  }, [token, refresh, navigate]);

  return (
    <div className="min-h-screen flex items-center justify-center">
      <div className="text-center">
        <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600 mx-auto mb-4" />
        <p className="text-gray-500">Redirecting to dashboard...</p>
      </div>
    </div>
  );
}
