import { createContext, createResource, createSignal, useContext, type ParentProps, type Accessor, type Setter } from 'solid-js';
import { useNavigate } from '@solidjs/router';

const API = '/api/gateway';

type AuthUser = {
  id: string;
  email: string;
  full_name: string;
  active_role: string;
  email_verified: boolean;
};

type AuthState = {
  user: Accessor<AuthUser | null>;
  isAuthenticated: Accessor<boolean>;
  isLoading: Accessor<boolean>;
  logout: () => void;
  setUser: Setter<AuthUser | null>;
};

const AuthContext = createContext<AuthState>();

function getToken(): string | null {
  if (typeof window === 'undefined') return null;
  return sessionStorage.getItem('nxtgauge_access_token') || null;
}

function clearAuthStorage() {
  if (typeof window === 'undefined') return;
  sessionStorage.removeItem('nxtgauge_access_token');
  sessionStorage.removeItem('nxtgauge_frontend_access_token');
  localStorage.removeItem('nxtgauge_auth_user');
  localStorage.removeItem('nxtgauge_user');
  localStorage.removeItem('nxtgauge_signup_profile_v1');
}

async function fetchSession(): Promise<AuthUser | null> {
  const token = getToken();
  if (!token) return null;
  try {
    const res = await fetch(`${API}/api/auth/session`, {
      headers: {
        Accept: 'application/json',
        Authorization: `Bearer ${token}`,
      },
      credentials: 'include',
    });
    if (!res.ok) return null;
    const data = await res.json();
    if (!data?.id && !data?.user_id) return null;
    return {
      id: data.id || data.user_id,
      email: data.email || '',
      full_name: data.full_name || data.name || '',
      active_role: data.active_role || data.role || 'JOB_SEEKER',
      email_verified: data.email_verified || false,
    };
  } catch {
    return null;
  }
}

export function AuthProvider(props: ParentProps) {
  const [user, setUser] = createSignal<AuthUser | null>(null);
  const [session] = createResource(fetchSession);

  const isLoading = () => session.loading;
  const isAuthenticated = () => !!user() || (!!session() && !session.error);

  if (session()) {
    setUser(session() as AuthUser | null);
  }

  const logout = () => {
    clearAuthStorage();
    setUser(null);
    if (typeof window !== 'undefined') {
      window.location.href = '/login';
    }
  };

  return (
    <AuthContext.Provider value={{ user, isAuthenticated, isLoading, logout, setUser }}>
      {props.children}
    </AuthContext.Provider>
  );
}

export function useAuth() {
  const ctx = useContext(AuthContext);
  if (!ctx) throw new Error('useAuth must be used within AuthProvider');
  return ctx;
}

export function RequireAuth(props: ParentProps<{ fallback?: string }>) {
  const navigate = useNavigate();
  const auth = useAuth();

  if (auth.isLoading()) {
    return <div class="flex min-h-screen items-center justify-center text-[#6B7280]">Loading...</div>;
  }

  if (!auth.isAuthenticated()) {
    const fallback = props.fallback || '/login';
    navigate(fallback, { replace: true });
    return null;
  }

  return <>{props.children}</>;
}

export { getToken, clearAuthStorage };
