import { createContext, createEffect, createResource, createSignal, useContext, onMount, Show, 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;
  roles?: string[];
};

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

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');
}

function normalizeRoleValue(value: unknown): string {
  return String(value || '').trim().toUpperCase().replace(/\s+/g, '_');
}

function isJobSeekerRole(roleKey: string): boolean {
  return normalizeRoleValue(roleKey) === 'JOB_SEEKER';
}

function getStoredPreferredRole(emailHint?: string): string | null {
  if (typeof window === 'undefined') return null;
  const keys = ['nxtgauge_signup_profile_v1', 'nxtgauge_auth_user', 'nxtgauge_user'];
  for (const key of keys) {
    const raw = window.localStorage.getItem(key);
    if (!raw) continue;
    try {
      const parsed = JSON.parse(raw) as Record<string, any>;
      const storedEmail = String(parsed?.email || '').trim().toLowerCase();
      if (emailHint && storedEmail && storedEmail !== emailHint.trim().toLowerCase()) continue;

      const selectedProfessionalRole = normalizeRoleValue(parsed?.selectedProfessionalRole);
      if (selectedProfessionalRole) return selectedProfessionalRole;

      const activeRole = normalizeRoleValue(parsed?.active_role || parsed?.role);
      if (activeRole) return activeRole;
    } catch {
      // Ignore malformed local storage payloads.
    }
  }
  return null;
}

function resolveActiveRole(rawBackendRole: unknown, emailHint?: string): string {
  const backendRole = normalizeRoleValue(rawBackendRole);
  const preferredRole = getStoredPreferredRole(emailHint);
  if (backendRole && preferredRole && isJobSeekerRole(backendRole) && !isJobSeekerRole(preferredRole)) {
    return preferredRole;
  }
  if (backendRole) return backendRole;
  if (preferredRole) return preferredRole;
  return '';
}

async function fetchSession(): Promise<AuthUser | null> {
  const token = getToken();
  if (!token) return null;
  try {
    const res = await fetch("/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;
    const resolvedActiveRole = resolveActiveRole(data.active_role || data.role, data.email || '');
    return {
      id: data.id || data.user_id,
      email: data.email || '',
      full_name: data.full_name || data.name || '',
      active_role: resolvedActiveRole,
      email_verified: data.email_verified || false,
      roles: data.roles || [],
    };
  } catch {
    return null;
  }
}

export function AuthProvider(props: ParentProps) {
  const [user, setUser] = createSignal<AuthUser | null>(null);
  const [sessionLoading, setSessionLoading] = createSignal(true);
  
  const refreshUser = (userData?: AuthUser | null) => {
    if (userData) {
      setUser(userData);
    } else {
      setSessionLoading(true);
      fetchSession().then(data => {
        setUser(data);
        setSessionLoading(false);
      });
    }
  };

  onMount(() => {
    fetchSession().then(data => {
      setUser(data);
      setSessionLoading(false);
    });
  });

  const isLoading = () => sessionLoading();
  const isAuthenticated = () => !!user() || !!getToken();

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

  return (
    <AuthContext.Provider value={{ user, isAuthenticated, isLoading, logout, setUser, refreshUser }}>
      {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) {
  const navigate = useNavigate();
  const [ready, setReady] = createSignal(false);
  
  createEffect(() => {
    if (ready()) {
      if (!getToken()) {
        navigate('/login', { replace: true });
      }
    }
  });
  
  onMount(() => {
    setReady(true);
  });

  return (
    <Show when={ready()} fallback={
      <div style={{ "min-height": "100vh", display: "flex", "align-items": "center", "justify-content": "center", background: "#F3F4F6", "font-family": "Inter, system-ui, sans-serif" }}>
        <div style={{ "text-align": "center" }}>
          <div style={{ width: "40px", height: "40px", border: "3px solid #FF5E13", "border-top-color": "transparent", "border-radius": "50%", animation: "spin 0.8s linear infinite", margin: "0 auto 12px" }} />
          <p style={{ color: "#6B7280", "font-size": "14px", margin: "0" }}>Loading...</p>
        </div>
        <style>{`@keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }`}</style>
      </div>
    }>
      {props.children}
    </Show>
  );
}

export function RequireAdmin(props: ParentProps) {
  const navigate = useNavigate();
  const auth = useAuth();
  const [checked, setChecked] = createSignal(false);
  
  createEffect(() => {
    if (checked()) {
      const user = auth.user();
      if (!user || !user.roles?.some(r => r === 'ADMIN' || r === 'SUPER_ADMIN')) {
        navigate('/dashboard', { replace: true });
      }
    }
  });
  
  onMount(() => {
    setChecked(true);
  });

  return (
    <Show when={checked() && auth.user()?.roles?.some(r => r === 'ADMIN' || r === 'SUPER_ADMIN')} fallback={
      <div style={{ "min-height": "100vh", display: "flex", "align-items": "center", "justify-content": "center", background: "#F3F4F6", "font-family": "Inter, system-ui, sans-serif" }}>
        <div style={{ "text-align": "center" }}>
          <div style={{ width: "40px", height: "40px", border: "3px solid #FF5E13", "border-top-color": "transparent", "border-radius": "50%", animation: "spin 0.8s linear infinite", margin: "0 auto 12px" }} />
          <p style={{ color: "#6B7280", "font-size": "14px", margin: "0" }}>Checking admin access...</p>
        </div>
        <style>{`@keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }`}</style>
      </div>
    }>
      {props.children}
    </Show>
  );
}

export function isAdmin(user: AuthUser | null): boolean {
  return user?.roles?.some(r => r === 'ADMIN' || r === 'SUPER_ADMIN') ?? false;
}

export { getToken, clearAuthStorage };
