<?php
// api/services/CotisationService.php

class CotisationService {

    private $db;

    public function __construct(PDO $conn) {
        $this->db = $conn;
    }

    /**
     * Montant mensuel selon l'année
     */
    private function getMontantMensuel(int $annee): float {
        return ($annee < 2024) ? 200.0 : 250.0;
    }

    /**
     * COTISATIONS + ARRERES + IMPAYES CALCULÉS
     */
    public function getCotisations(int $membre_id): array {

        /**
         * 1) Vérifier l’existence du membre
         */
        $stmt = $this->db->prepare("SELECT date_adhesion FROM membres WHERE id = ?");
        $stmt->execute([$membre_id]);
        $row = $stmt->fetch(PDO::FETCH_ASSOC);

        if (!$row) {
            return ["success" => false, "message" => "Membre introuvable."];
        }

        $dateAdhesion = $row["date_adhesion"];

        /**
         * 2) Préparer la période mensuelle
         */
        $start = new DateTime($dateAdhesion);
        $start->modify("first day of this month");

        $end = new DateTime();
        $end->modify("first day of this month");

        /**
         * 3) COTISATIONS PAYÉES
         */
        $sql = $this->db->prepare("
            SELECT annee, mois, montant, created_at
            FROM cotisations_membres
            WHERE membre_id = ?
            ORDER BY annee DESC, mois DESC
        ");
        $sql->execute([$membre_id]);
        $paye = $sql->fetchAll(PDO::FETCH_ASSOC);

        // Clés de type "2025-02"
        $payesSet = [];
        foreach ($paye as $c) {
            $key = sprintf("%04d-%02d", $c["annee"], $c["mois"]);
            $payesSet[$key] = true;
        }

        /**
         * 4) ARRERES EXISTANTS
         */
        $sql2 = $this->db->prepare("
            SELECT annee, mois, montant_du, statut
            FROM historiques_arriere
            WHERE membre_id = ?
        ");
        $sql2->execute([$membre_id]);
        $arrieres = $sql2->fetchAll(PDO::FETCH_ASSOC);

        $arrSet = [];
        foreach ($arrieres as $a) {
            $key = sprintf("%04d-%02d", $a["annee"], $a["mois"]);
            $arrSet[$key] = true;
        }

        /**
         * 5) IMPAYÉS CALCULÉS
         */
        $impayesCalcules = [];

        $period = new DatePeriod(
            $start,
            new DateInterval("P1M"),
            (clone $end)->modify("+1 month")
        );

        foreach ($period as $dt) {

            $annee = intval($dt->format("Y"));
            $mois  = intval($dt->format("m"));
            $key   = sprintf("%04d-%02d", $annee, $mois);

            // Déjà payé ou déjà en arriéré → ignorer
            if (isset($payesSet[$key]) || isset($arrSet[$key])) {
                continue;
            }

            $montant = $this->getMontantMensuel($annee);

            $impayesCalcules[] = [
                "annee"       => $annee,
                "mois"        => $mois,
                "montant_du"  => $montant,
                "type"        => "impaye_calcule"
            ];
        }

        return [
            "success" => true,
            "data" => [
                "membre_id" => $membre_id,
                "date_adhesion" => $dateAdhesion,
                "mois_payes" => $paye,
                "mois_impayes" => $arrieres,
                "mois_impayes_calcules" => $impayesCalcules
            ]
        ];
    }

    /**
     * AJOUTER UNE COTISATION
     */
    public function ajouterCotisation(array $data): array {

        $membre_id = intval($data["membre_id"]);
        $annee     = intval($data["annee"]);
        $mois      = intval($data["mois"]);

        $montant = $this->getMontantMensuel($annee);

        try {
            $this->db->beginTransaction();

            /**
             * Vérifier si déjà payé
             */
            $chk = $this->db->prepare("
                SELECT id
                FROM cotisations_membres
                WHERE membre_id = ? AND annee = ? AND mois = ?
            ");
            $chk->execute([$membre_id, $annee, $mois]);

            if ($chk->rowCount() > 0) {
                return ["success" => false, "message" => "Cotisation déjà payée."];
            }

            /**
             * 1) CRÉER OPÉRATION
             */
            $op = $this->db->prepare("
                INSERT INTO operations (type, montant, description, categorie_id, date_operation, created_by)
                VALUES ('recette', ?, 'Paiement cotisation', 1, CURDATE(), ?)
            ");
            $op->execute([$montant, $membre_id]);
            $operation_id = $this->db->lastInsertId();

            /**
             * 2) AJOUTER COTISATION
             */
            $ins = $this->db->prepare("
                INSERT INTO cotisations_membres (membre_id, annee, mois, montant, operation_id)
                VALUES (?, ?, ?, ?, ?)
            ");
            $ins->execute([$membre_id, $annee, $mois, $montant, $operation_id]);

            /**
             * 3) SUPPRIMER ARRÉRÉ SI EXISTE
             */
            $del = $this->db->prepare("
                DELETE FROM historiques_arriere
                WHERE membre_id = ? AND annee = ? AND mois = ?
            ");
            $del->execute([$membre_id, $annee, $mois]);

            $this->db->commit();

            return [
                "success" => true,
                "message" => "Cotisation enregistrée.",
                "data" => [
                    "membre_id" => $membre_id,
                    "annee"     => $annee,
                    "mois"      => $mois,
                    "montant"   => $montant
                ]
            ];

        } catch (Exception $e) {

            if ($this->db->inTransaction()) {
                $this->db->rollBack();
            }

            return [
                "success" => false,
                "message" => "Erreur paiement : " . $e->getMessage()
            ];
        }
    }

    /**
     * HISTORIQUE GLOBAL
     */
    public function getHistoriqueByMembre(int $membre_id): array {

        try {
            /**
             * 1) Cotisations
             */
            $q1 = $this->db->prepare("
                SELECT 'cotisation' AS type, annee, mois, montant, created_at AS date
                FROM cotisations_membres
                WHERE membre_id = ?
            ");
            $q1->execute([$membre_id]);
            $cotisations = $q1->fetchAll(PDO::FETCH_ASSOC);

            /**
             * 2) Impayés (arriérés)
             */
            $q2 = $this->db->prepare("
                SELECT 'impaye' AS type, annee, mois, montant_du AS montant, created_at AS date
                FROM historiques_arriere
                WHERE membre_id = ?
            ");
            $q2->execute([$membre_id]);
            $impayes = $q2->fetchAll(PDO::FETCH_ASSOC);

            /**
             * 3) Dons
             */
            $q3 = $this->db->prepare("
                SELECT 'don' AS type, NULL AS annee, NULL AS mois, montant, commentaire, created_at AS date
                FROM dons_membres
                WHERE membre_id = ?
            ");
            $q3->execute([$membre_id]);
            $dons = $q3->fetchAll(PDO::FETCH_ASSOC);

            /**
             * 4) Autres cotisations
             */
            $q4 = $this->db->prepare("
                SELECT 'autre' AS type, NULL AS annee, NULL AS mois, montant, commentaire, created_at AS date
                FROM autres_cotisations
                WHERE membre_id = ?
            ");
            $q4->execute([$membre_id]);
            $autres = $q4->fetchAll(PDO::FETCH_ASSOC);

            /**
             * FUSION
             */
            $historique = array_merge($cotisations, $impayes, $dons, $autres);

            /**
             * TRI DESC
             */
            usort($historique, function($a, $b) {
                return strtotime($b["date"]) - strtotime($a["date"]);
            });

            return [
                "success" => true,
                "membre_id" => $membre_id,
                "historique" => $historique
            ];

        } catch (Exception $e) {

            return [
                "success" => false,
                "message" => "Erreur historique : " . $e->getMessage()
            ];
        }
    }
}
