<?php

/**
 * Point UNIQUE de détermination du statut d'un objet céleste.
 * Basé sur les règles configurées dans l'administration.
 */
function calculateCelestialStatus($planet, $db, $statuses_map) {
    $profile_id = $planet['status_profile_id'] ?? null;
    
    // Si pas de profil sur la planète, on prend celui du type d'objet
    if (!$profile_id && isset($planet['type'])) {
        $stmt = $db->prepare("SELECT status_profile_id FROM celestial_object_types WHERE slug = ?");
        $stmt->execute([$planet['type']]);
        $profile_id = $stmt->fetchColumn();
    }

    // Si toujours pas de profil, on retourne le statut actuel (fallback alpha)
    if (!$profile_id) {
        return $planet['status'];
    }

    // Récupération des règles du profil par priorité
    $stmt = $db->prepare("SELECT r.*, s.slug as status_slug 
                          FROM celestial_object_status_rules r 
                          JOIN celestial_object_statuses s ON r.status_id = s.id 
                          WHERE r.profile_id = ? AND r.is_active = 1 
                          ORDER BY r.priority DESC, r.id ASC");
    $stmt->execute([$profile_id]);
    $rules = $stmt->fetchAll(PDO::FETCH_ASSOC);

    // Préparation des données de l'objet pour l'évaluation
    $orbital_controls = $planet['orbital_controls'] ?? [];
    $terrestrial_controls = $planet['terrestrial_controls'] ?? [];

    // On exclut la faction "Aucune" (ID 1) et les valeurs nulles des comptes
    $orbital_factions = array_filter($orbital_controls, fn($v, $k) => $v > 0 && $k != 1, ARRAY_FILTER_USE_BOTH);
    $terrestrial_factions = array_filter($terrestrial_controls, fn($v, $k) => $v > 0 && $k != 1, ARRAY_FILTER_USE_BOTH);

    $orb_count = count($orbital_factions);
    $terr_count = count($terrestrial_factions);

    $orb_dom = null;
    if ($orb_count > 0) {
        arsort($orbital_factions);
        $orb_dom = array_key_first($orbital_factions);
    }

    $terr_dom = null;
    if ($terr_count > 0) {
        arsort($terrestrial_factions);
        $terr_dom = array_key_first($terrestrial_factions);
    }

    $is_empty = ($orb_count === 0 && $terr_count === 0);

    // Évaluation des règles
    foreach ($rules as $rule) {
        // Condition Case Vide (doit matcher avant de tester le reste)
        if ($rule['is_empty_case'] && !$is_empty) continue;

        $match_orbite = true;
        $match_sol = true;
        
        $has_orb_cond = !empty($rule['orbital_count_op']) || !empty($rule['orbital_dominance']);
        $has_sol_cond = !empty($rule['terrestrial_count_op']) || !empty($rule['terrestrial_dominance']);

        // Evaluation Orbite
        if ($rule['orbital_count_op']) {
            if (!evaluateOperator($orb_count, $rule['orbital_count_op'], $rule['orbital_count_val'])) {
                $match_orbite = false;
            }
        }
        if ($match_orbite && !empty($rule['orbital_dominance'])) {
            $allowed = explode(',', $rule['orbital_dominance']);
            $isIn = false;
            if (!$orb_dom) {
                if (in_array('none', $allowed)) $isIn = true;
            } else {
                if (in_array((string)$orb_dom, $allowed)) $isIn = true;
            }
            if (!$isIn) $match_orbite = false;
        }

        // Evaluation Sol
        if ($rule['terrestrial_count_op']) {
            if (!evaluateOperator($terr_count, $rule['terrestrial_count_op'], $rule['terrestrial_count_val'])) {
                $match_sol = false;
            }
        }
        if ($match_sol && !empty($rule['terrestrial_dominance'])) {
            $allowed = explode(',', $rule['terrestrial_dominance']);
            $isIn = false;
            if (!$terr_dom) {
                if (in_array('none', $allowed)) $isIn = true;
            } else {
                if (in_array((string)$terr_dom, $allowed)) $isIn = true;
            }
            if (!$isIn) $match_sol = false;
        }

        // Application de la combinaison
        $combine = $rule['combine_mode'] ?? 'OR';
        $final_match = false;

        if (!$has_orb_cond && !$has_sol_cond) {
            // Pas de conditions spécifiques (ex: règle par défaut ou juste is_empty_case)
            $final_match = true;
        } elseif ($has_orb_cond && !$has_sol_cond) {
            $final_match = $match_orbite;
        } elseif (!$has_orb_cond && $has_sol_cond) {
            $final_match = $match_sol;
        } else {
            // Les deux côtés ont des conditions
            if ($combine === 'AND') {
                $final_match = $match_orbite && $match_sol;
            } else {
                $final_match = $match_orbite || $match_sol;
            }
        }

        // Condition Croisée (Dominance différente requise)
        if ($final_match && ($rule['dominance_diff_required'] ?? 0)) {
            if ($orb_dom == $terr_dom) $final_match = false;
        }

        if ($final_match) {
            return $rule['status_slug'];
        }
    }

    // Fallback final si profil présent mais aucune règle ne matche
    return 'sta_inhabited';
}

function evaluateOperator($val, $op, $target) {
    switch ($op) {
        case '=': return $val == $target;
        case '>': return $val > $target;
        case '<': return $val < $target;
        case '>=': return $val >= $target;
        case '<=': return $val <= $target;
        case '!=': return $val != $target;
    }
    return true;
}