'use client';

import { createContext, useContext, useEffect, useState, useCallback, ReactNode } from 'react';
import i18n from "@/lib/i18n";

interface AuthUser {
  id: string;
  name: string;
  email: string;
  role: string;
  roles: { id: string; code: string; name_ar: string; name_en: string | null }[];
  permissions: string[];
  user_type: string;
  status: string;
}

interface AuthContextType {
  user: AuthUser | null;
  token: string | null;
  logout: () => void;
  isLoading: boolean;
  setAuth: (token: string, user: AuthUser) => void;
}

const AuthContext = createContext<AuthContextType | undefined>(undefined);

function syncFromCookies() {
  if (typeof document === 'undefined') return;

  const getCookie = (name: string) => {
    const match = document.cookie.match(new RegExp('(?:^|; )' + name.replace(/([.$?*|{}()\[\]\\\/\+^])/g, '\\$1') + '=([^;]*)'));
    return match ? decodeURIComponent(match[1]) : null;
  };

  const cookieToken = getCookie('auth_token');
  const cookieUser = getCookie('auth_user');

  if (cookieToken && !localStorage.getItem('auth_token')) {
    localStorage.setItem('auth_token', cookieToken);
  }
  if (cookieUser) {
    const storedUser = localStorage.getItem('auth_user');
    if (!storedUser || !parseStoredUser(storedUser)) {
      localStorage.setItem('auth_user', decodeCookieJson(cookieUser));
    }
  }
}

function decodeCookieJson(value: string) {
  try {
    return decodeURIComponent(value);
  } catch {
    return value;
  }
}

function parseStoredUser(value: string): AuthUser | null {
  const candidates = [value, decodeCookieJson(value)];

  for (const candidate of candidates) {
    try {
      return JSON.parse(candidate);
    } catch {
      // Try the next representation.
    }
  }

  return null;
}

export function AuthProvider({ children }: { children: ReactNode }) {
  const [user, setUser] = useState<AuthUser | null>(null);
  const [token, setToken] = useState<string | null>(null);
  const [isLoading, setIsLoading] = useState(true);

  useEffect(() => {
    syncFromCookies();

    const storedToken = localStorage.getItem('auth_token');
    const storedUser = localStorage.getItem('auth_user');

    setToken(storedToken);

    if (storedUser) {
      const parsedUser = parseStoredUser(storedUser);
      if (parsedUser) {
        setUser(parsedUser);
        localStorage.setItem('auth_user', JSON.stringify(parsedUser));
      } else {
        localStorage.removeItem('auth_user');
        setUser(null);
      }
    }

    setIsLoading(false);
  }, []);

  const setAuth = useCallback((newToken: string, newUser: AuthUser) => {
    const userPayload = JSON.stringify(newUser);
    localStorage.setItem('auth_token', newToken);
    localStorage.setItem('auth_user', userPayload);
    if (typeof document !== 'undefined') {
      document.cookie = `auth_token=${encodeURIComponent(newToken)}; path=/; max-age=${60 * 60 * 24 * 7}`;
      document.cookie = `auth_user=${encodeURIComponent(userPayload)}; path=/; max-age=${60 * 60 * 24 * 7}`;
    }
    setToken(newToken);
    setUser(newUser);
  }, []);

  const logout = useCallback(() => {
    setToken(null);
    setUser(null);
    if (typeof window !== 'undefined') {
      localStorage.removeItem('auth_token');
      localStorage.removeItem('auth_user');
      window.location.href = '/login';
    }
  }, []);

  const [isSessionExpired, setIsSessionExpired] = useState(false);
  const [isRefreshing, setIsRefreshing] = useState(false);

  useEffect(() => {
    const handleSessionExpired = () => {
      setIsSessionExpired(true);
    };

    window.addEventListener('session-expired', handleSessionExpired);
    return () => {
      window.removeEventListener('session-expired', handleSessionExpired);
    };
  }, []);

  const handleRefreshSession = async () => {
    setIsRefreshing(true);
    try {
      const { api } = await import('@/lib/api');
      const res = await api.post('auth/refresh');
      const newToken = res?.data?.access_token ?? res?.access_token;
      if (newToken) {
        // Update token in memory and storage — NO page reload needed
        setToken(newToken);
        localStorage.setItem('auth_token', newToken);
        // Also sync to cookie so Next.js middleware sees the fresh token
        document.cookie = `auth_token=${newToken}; path=/; max-age=${60 * 60 * 24}`;
        setIsSessionExpired(false);
      } else {
        // No token in response — force logout
        logout();
      }
    } catch {
      // Refresh failed (expired refresh token) — force logout
      logout();
    } finally {
      setIsRefreshing(false);
    }
  };

  return (
    <AuthContext.Provider value={{ user, token, logout, isLoading, setAuth }}>
      {children}
      {isSessionExpired && (
        <div className="fixed inset-0 z-[100] bg-background/80 backdrop-blur-sm flex items-center justify-center p-4">
          <div className="bg-card w-full max-w-sm rounded-lg shadow-lg border border-border p-6 flex flex-col items-center text-center space-y-4">
            <div className="w-12 h-12 rounded-full bg-amber-500/10 flex items-center justify-center text-amber-500 mb-2">
              <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z"/><path d="M12 9v4"/><path d="M12 17h.01"/></svg>
            </div>
            <h3 className="text-xl font-bold">{i18n.t('contexts.auth-context.text_2')}</h3>
            <p className="text-muted-foreground text-sm">
              {i18n.t('contexts.auth-context.text_3')}</p>
            <div className="flex w-full gap-3 pt-2">
              <button 
                onClick={logout}
                className="flex-1 h-10 px-4 rounded-md border border-border hover:bg-muted text-sm font-medium transition-colors"
              >
                {i18n.t('contexts.auth-context.text_4')}</button>
              <button 
                onClick={handleRefreshSession}
                disabled={isRefreshing}
                className="flex-1 h-10 px-4 rounded-md bg-gold-500 text-ink-900 hover:bg-gold-600 disabled:opacity-50 shadow-sm text-sm font-medium transition-colors flex items-center justify-center"
              >
                {isRefreshing ? (
                  <span className="w-4 h-4 border-2 border-current border-t-transparent animate-spin rounded-full"></span>
                ) : (
                  i18n.t('contexts.auth-context.text_1')
                )}
              </button>
            </div>
          </div>
        </div>
      )}
    </AuthContext.Provider>
  );
}

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