/**
 * Store Zustand pour l'authentification - COOP-CA AMIFOND
 *
 * Gestion centralisée de l'état d'authentification avec Zustand
 * V2 - Utilise les cookies HttpOnly pour le stockage des tokens.
 */

import { create } from "zustand";
import { devtools, persist } from "zustand/middleware";

import { apiEndpoints } from "@/lib/api-config";
import type { LoginRequest, RegisterRequest, User, AuthError } from "@/types/auth";

// Interface mise à jour : plus de gestion de tokens ou de refreshToken
interface AuthStore {
  isAuthenticated: boolean;
  isLoading: boolean;
  user: User | null;
  error: AuthError | null;
  loginError: AuthError | null;
  registerError: AuthError | null;
  login: (credentials: LoginRequest) => Promise<void>;
  register: (data: RegisterRequest) => Promise<void>;
  logout: () => Promise<void>;
  updateUser: (user: User) => void;
  clearError: () => void;
  checkAuthStatus: () => Promise<void>; // Renommée pour plus de clarté
  setIsLoading: (isLoading: boolean) => void;
}

// Fonction utilitaire pour transformer les erreurs (inchangée)
const transformError = (error: unknown): AuthError => {
  const errorObj = error as Record<string, unknown>;

  if (errorObj.data && typeof errorObj.data === "object") {
    const data = errorObj.data as Record<string, unknown>;

    const fieldErrors: Record<string, string[]> = {};
    let hasFieldErrors = false;

    for (const [field, messages] of Object.entries(data)) {
      if (Array.isArray(messages) && field !== "non_field_errors") {
        fieldErrors[field] = messages as string[];
        hasFieldErrors = true;
      }
    }

    if (hasFieldErrors) {
      const firstFieldError = Object.values(fieldErrors)[0]?.[0] || "Erreur de validation";
      return {
        message: firstFieldError,
        details: fieldErrors,
        data: data,
      };
    }

    if (data.non_field_errors && Array.isArray(data.non_field_errors)) {
      const firstError = data.non_field_errors[0] as string;
      return {
        message: firstError || "Erreur de validation",
        data: data,
      };
    }

    if (data.detail) {
      return {
        message: data.detail as string,
        data: data,
      };
    }
  }

  return {
    message: (errorObj.message as string) || "Une erreur inattendue s'est produite",
    data: errorObj.data,
  };
};

const API_BASE_URL = process.env.NEXT_PUBLIC_API_URL;

export const useAuthStore = create<AuthStore>()(
  devtools(
    persist(
      (set, get) => ({
        // État initial simplifié
        isAuthenticated: false,
        isLoading: true, // Commence en chargement pour la vérification initiale
        user: null,
        // tokens: null, // SUPPRIMÉ
        error: null,
        loginError: null,
        registerError: null,

        // Action de connexion mise à jour
        login: async (credentials: LoginRequest) => {
          set({ isLoading: true, loginError: null, error: null });

          try {
            const response = await fetch(`${API_BASE_URL}${apiEndpoints.auth.login}`, {
              method: "POST",
              headers: { "Content-Type": "application/json" },
              body: JSON.stringify(credentials),
              credentials: 'include', // <-- TRÈS IMPORTANT
            });

            if (!response.ok) {
              const errorData = await response.json();
              throw { data: errorData };
            }

            const data: { user: User } = await response.json(); // La réponse ne contient plus que l'utilisateur

            set({
              isAuthenticated: true,
              user: data.user,
              isLoading: false,
            });
          } catch (error: unknown) {
            const authError = transformError(error);
            set({
              isLoading: false,
              loginError: authError,
              error: authError,
              isAuthenticated: false,
              user: null,
            });
            throw error;
          }
        },

        // Action d'inscription (inchangée, car elle ne connecte pas l'utilisateur)
        register: async (data: RegisterRequest) => {
          set({ isLoading: true, registerError: null, error: null });

          try {
            const response = await fetch(`${API_BASE_URL}${apiEndpoints.auth.register}`, {
              method: "POST",
              headers: {
                "Content-Type": "application/json",
              },
              body: JSON.stringify(data),
            });

            if (!response.ok) {
              const errorData = await response.json();
              const errorMessage = errorData.detail || errorData.message || "Registration failed";
              const error = new Error(errorMessage);
              (error as Error & { data?: unknown }).data = errorData;
              throw error;
            }

            set({
              isLoading: false,
              registerError: null,
              error: null,
            });
          } catch (error: unknown) {
            const authError = transformError(error);
            set({
              isLoading: false,
              registerError: authError,
              error: authError,
            });
            throw error;
          }
        },

        // Action de déconnexion mise à jour
        logout: async () => {
          set({ isLoading: true });
          try {
            // Appelle le backend qui se chargera de supprimer les cookies HttpOnly
            await fetch(`${API_BASE_URL}${apiEndpoints.auth.logout}`, {
              method: "POST",
              credentials: 'include', // <-- TRÈS IMPORTANT
            });
          } catch (error) {
            console.warn("Erreur lors de la déconnexion (backend):", error);
          } finally {
            // Réinitialise toujours l'état local
            set({
              isAuthenticated: false,
              isLoading: false,
              user: null,
              error: null,
              loginError: null,
              registerError: null,
            });
          }
        },

        // refreshToken: async () => {}, // SUPPRIMÉ

        // Action pour vérifier le statut d'authentification au démarrage
        checkAuthStatus: async () => {
          set({ isLoading: true });
          try {
            // Fait un appel à un endpoint protégé. Si ça marche, l'utilisateur est connecté.
            const response = await fetch(`${API_BASE_URL}${apiEndpoints.auth.me}`, {
              method: 'GET',
              credentials: 'include', // <-- TRÈS IMPORTANT
            });

            if (!response.ok) {
              throw new Error("Session invalide ou expirée");
            }

            const user: User = await response.json();
            set({ isAuthenticated: true, user, isLoading: false });

          } catch (error) {
            // Si l'appel échoue, l'utilisateur n'est pas authentifié.
            set({ isAuthenticated: false, user: null, isLoading: false });
          }
        },

        // updateUser (inchangé)
        updateUser: (user: User) => {
          set({ user });
        },

        // clearError (inchangé)
        clearError: () => {
          set({ error: null, loginError: null, registerError: null });
        },

        // setIsLoading (inchangé)
        setIsLoading: (isLoading: boolean) => {
          set({ isLoading });
        },
      }),
      {
        name: "amifond-auth-status", // Nom différent pour éviter les conflits avec l'ancien store
        partialize: (state) => ({
          // Ne persister que l'état d'authentification et l'utilisateur
          isAuthenticated: state.isAuthenticated,
          user: state.user,
        }),
      }
    ),
    {
      name: "auth-store",
    }
  )
);

// Selectors pour une utilisation optimisée
export const useAuth = () => {
  const isAuthenticated = useAuthStore((state) => state.isAuthenticated);
  const isLoading = useAuthStore((state) => state.isLoading);
  const user = useAuthStore((state) => state.user);
  const error = useAuthStore((state) => state.error);

  return { isAuthenticated, isLoading, user, error };
};

export const useAuthActions = () => {
  const login = useAuthStore((state) => state.login);
  const register = useAuthStore((state) => state.register);
  const logout = useAuthStore((state) => state.logout);
  const updateUser = useAuthStore((state) => state.updateUser);
  const clearError = useAuthStore((state) => state.clearError);
  const checkAuthStatus = useAuthStore((state) => state.checkAuthStatus);

  return { login, register, logout, updateUser, clearError, checkAuthStatus };
};

export const useAuthErrors = () => {
  const loginError = useAuthStore((state) => state.loginError);
  const registerError = useAuthStore((state) => state.registerError);
  const error = useAuthStore((state) => state.error);
  const clearError = useAuthStore((state) => state.clearError);

  return { loginError, registerError, error, clearError };
};

// Fonction utilitaire pour vérifier les permissions
export const usePermissions = () => {
  const user = useAuthStore((state) => state.user);

  // Les user_type sont maintenant basés sur le nouveau backend.
  // Ex: 'super_admin', 'ca_member', 'manager', 'account_manager', 'cashier', 'client', 'it_staff', 'other_staff'

  return {
    // Un admin est un super_admin ou un membre du CA
    isAdmin: user?.user_type === "super_admin" || user?.user_type === "ca_member",
    // Un manager a des droits de gestion étendus
    isManager: user?.user_type && ["super_admin", "ca_member", "manager"].includes(user.user_type),
    // Un employé est toute personne qui n'est pas un simple client
    isStaff: user?.is_staff === true,
    // Un client est spécifiquement du type 'client'
    isClient: user?.user_type === "client",
    // Permission de gérer d'autres utilisateurs
    canManageUsers: (user?.permissions_level ?? 0) >= 80, // Exemple basé sur le niveau de permission
    // Permission d'accéder aux rapports financiers
    canAccessReports: user?.user_type && ["super_admin", "ca_member", "manager", "account_manager"].includes(user.user_type),
  };
};
