import { computed } from 'vue';
import { usePage } from '@inertiajs/vue3';
import { UserAbilityCode } from '@/constants/ability/abilities';

// --
// 1. DÉCLARATION DES INTERFACES
// --

export interface Ability {
  id?: number;
  code: UserAbilityCode;
  name?: string;
}

export interface Role {
  id?: number;
  name: string;
}

export interface ClientAdmin {
  id?: number;
  name: string;
  is_entreprise?: boolean;
}

export interface IAuthFlags {
  has_client: boolean;
  is_demo: boolean;
}

export interface UserPi {
  id: number | null;
  civility: string | null;
  first_name: string;
  last_name: string;
  nickname: string;
  email: string;
  phone: string | null;
  is_verified: boolean;
  roles: Role[];
  abilities: Ability[];
}

/**
 * Structure globale attendue depuis HandleInertiaRequests.php
 */
export interface AuthPayload {
  user: UserPi | null;
  client: ClientAdmin | null;
  flags: IAuthFlags;
}

// --
// 2. LE COMPOSABLE : useAuthUser
// --

/**
 * Composable universel pour savoir si l'utilisateur est connecté 
 * et récupérer toutes ses informations (Droits, Client, Profil) n'importe où.
 */
export const useAuthUser = () => {
  const page = usePage();

  // On récupère le payload 'auth' et on le type strictement
  const authPayload = computed(() => (page.props.auth as AuthPayload) || {});
  
  //  ÉTAT GLOBAL 
  const isAuthenticated = computed(() => !!authPayload.value?.user);
  
  //  OBJETS COMPLETS 
  const user = computed(() => authPayload.value?.user ?? null);
  const clientAdmin = computed(() => authPayload.value?.client ?? null);
  const flags = computed(() => authPayload.value?.flags ?? { has_client: false, is_demo: false });

  //  RACCOURCIS PROFIL UTILISATEUR 
  const userId = computed(() => user.value?.id ?? null);
  const nickname = computed(() => user.value?.nickname ?? '');
  const email = computed(() => user.value?.email ?? '');
  const isVerified = computed(() => user.value?.is_verified ?? false);
  
  //  RACCOURCIS DROITS ET RÔLES 
  const roles = computed(() => user.value?.roles ?? []);
  const abilities = computed(() => user.value?.abilities ?? []);

  //  RACCOURCIS FLAGS 
  const isDemo = computed(() => flags.value.is_demo);
  const hasClient = computed(() => flags.value.has_client);
  
  // Logique métier : l'utilisateur est prêt s'il a vérifié son email ET qu'il a un client
  const userValide = computed(() => isVerified.value && hasClient.value);

  //  MÉTHODES UTILITAIRES 
  
  /**
   * Vérifie si l'utilisateur possède une permission spécifique (ex: 'can.app.access')
   */
  const hasAbility = (code: UserAbilityCode): boolean => {
    return abilities.value.some(a => a.code === code);
  };

  /**
   * Vérifie si l'utilisateur possède un rôle spécifique (ex: 'Admin client')
   */
  const hasRole = (roleName: string): boolean => {
    return roles.value.some(r => r.name === roleName);
  };

  const can = computed(() => {
    const map: Record<string, boolean> = {};
    abilities.value.forEach(a => {
      map[a.code] = true;
    });
    return map;
  });

  return {
    // États
    isAuthenticated,
    userValide,
    
    // Objets
    user,
    clientAdmin,
    flags,
    
    // Raccourcis
    userId,
    nickname,
    email,
    isVerified,
    roles,
    abilities,
    isDemo,
    hasClient,

    // Méthodes
    hasAbility,
    can,
    hasRole
  };
};