<?php

declare(strict_types=1);

namespace App\Controllers;

use App\Models\User;
use App\Services\PrestashopService;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Illuminate\Database\Capsule\Manager as DB;

class UserAdminController
{
    use ControllerTrait;

    // DELETE /api/admin/users/:id
    // Auth : super_admin uniquement
    //
    // Supprime un compte sportif dans les deux bases :
    //   1. Vérifie qu'aucune commande active (en_lot / en_gravure) n'existe
    //   2. Anonymise dans mykollufab (RGPD — ne jamais supprimer les commandes)
    //   3. Soft-delete dans PS (deleted=1) via SQL direct PrestashopService
    //   4. Révoque toutes les sessions JWT
    //   5. Log dans logs_audit
    //
    // RÈGLES RGPD (bible §13.2) :
    //   - JAMAIS supprimer les commandes (obligation légale 10 ans)
    //   - Anonymisation : email / prenom / nom / strava effacés — anonymized_at renseigné
    //   - Les chronos sont conservés (données sportives non nominatives après anonymisation)

    public function deleteUser(Request $request, Response $response, array $args): Response
    {
        $admin = $this->getAuthUser($request);
        if (!$admin || $admin->role !== 'super_admin') {
            return $this->error($response, 'FORBIDDEN', 'Accès réservé au super_admin', 403);
        }

        $userId = (int)($args['id'] ?? 0);
        if (!$userId) {
            return $this->error($response, 'VALIDATION_ERROR', 'ID utilisateur requis', 400);
        }

        // Ne pas se supprimer soi-même
        if ($userId === $admin->id) {
            return $this->error($response, 'FORBIDDEN', 'Impossible de supprimer votre propre compte', 403);
        }

        $user = User::find($userId);
        if (!$user) {
            return $this->error($response, 'NOT_FOUND', 'Utilisateur introuvable', 404);
        }

        // ── Bloquer si commande en cours ──────────────────────────────────────
        $commandeActive = DB::table('commandes')
            ->where('user_id', $userId)
            ->whereIn('statut', ['en_lot', 'en_gravure'])
            ->exists();

        if ($commandeActive) {
            return $this->error(
                $response,
                'COMMANDE_EN_COURS',
                'Impossible de supprimer ce compte — une commande est en_lot ou en_gravure',
                409
            );
        }

        // ── Snapshot avant suppression pour log_audit ─────────────────────────
        $snapshot = [
            'email'              => $user->email,
            'prenom'             => $user->prenom,
            'nom'                => $user->nom,
            'role'               => $user->role,
            'presta_customer_id' => $user->presta_customer_id,
            'date_inscription'   => $user->date_inscription,
            'supprime_par'       => $admin->id,
        ];

        DB::beginTransaction();
        try {

            // ── 1. Révoquer toutes les sessions JWT ───────────────────────────
            DB::table('sessions')->where('user_id', $userId)->delete();

            // ── 2. Anonymisation RGPD dans mykollufab ─────────────────────────
            // On ne supprime PAS la ligne — on efface les données personnelles
            // Les commandes et chronos restent liés à l'ID anonymisé
            User::where('id', $userId)->update([
                'email'                => 'anonymized_' . $userId . '@deleted.mykollector.com',
                'password'             => null,
                'prenom'               => null,
                'nom'                  => null,
                'reset_token'          => null,
                'reset_expires'        => null,
                'strava_connected'     => 0,
                'strava_id'            => null,
                'strava_access_token'  => null,
                'strava_refresh_token' => null,
                'strava_token_expires' => null,
                'actif'                => 0,
                'anonymized_at'        => date('Y-m-d H:i:s'),
            ]);

            // ── 3. Soft-delete dans PrestaShop ────────────────────────────────
            if ($user->presta_customer_id) {
                try {
                    $ps = new PrestashopService();
                    $ps->softDeleteCustomer((int)$user->presta_customer_id);
                } catch (\Exception $e) {
                    // Non bloquant — PS peut déjà avoir supprimé le compte
                    error_log('[UserAdminController::deleteUser] PS soft-delete échoué pour presta_id='
                        . $user->presta_customer_id . ' : ' . $e->getMessage());
                }
            }

            // ── 4. Log audit ──────────────────────────────────────────────────
            $this->logAudit(
                $admin->id,
                'user_supprime',
                'user',
                $userId,
                $snapshot,
                $request
            );

            DB::commit();

            return $this->success($response, [
                'message'        => 'Compte anonymisé et supprimé de PrestaShop.',
                'user_id'        => $userId,
                'anonymized_at'  => date('Y-m-d H:i:s'),
            ]);

        } catch (\Exception $e) {
            DB::rollBack();
            error_log('[UserAdminController::deleteUser] ' . $e->getMessage());
            return $this->error($response, 'INTERNAL_ERROR', 'Erreur interne', 500);
        }
    }

    // GET /api/admin/users — Liste des sportifs (super_admin)
    // Utile pour retrouver l'ID avant suppression
    public function listUsers(Request $request, Response $response): Response
    {
        $admin = $this->getAuthUser($request);
        if (!$admin || $admin->role !== 'super_admin') {
            return $this->error($response, 'FORBIDDEN', 'Accès réservé au super_admin', 403);
        }

        $params  = $request->getQueryParams();
        $search  = trim($params['q'] ?? '');
        $page    = max(1, (int)($params['page'] ?? 1));
        $perPage = 50;

        $query = User::where('anonymized_at', null)
            ->where('role', 'sportif')
            ->orderBy('date_inscription', 'desc');

        if ($search) {
            $query->where(function ($q) use ($search) {
                $q->where('email', 'like', '%' . $search . '%')
                  ->orWhere('prenom', 'like', '%' . $search . '%')
                  ->orWhere('nom', 'like', '%' . $search . '%');
            });
        }

        $total = $query->count();
        $users = $query->skip(($page - 1) * $perPage)
            ->take($perPage)
            ->get(['id', 'email', 'prenom', 'nom', 'actif', 'presta_customer_id',
                   'strava_connected', 'date_inscription', 'derniere_connexion']);

        return $this->success($response, [
            'users' => $users,
            'total' => $total,
            'page'  => $page,
            'pages' => (int)ceil($total / $perPage),
        ]);
    }
}
