<?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 UserController
{
    use ControllerTrait;

    public function __construct(
        private PrestashopService $ps
    ) {}

    public function updateProfil(Request $request, Response $response): Response
    {
        $user = $this->getAuthUser($request);
        if (!$user) return $this->error($response, 'UNAUTHORIZED', 'Non authentifié', 401);

        $body   = (array)$request->getParsedBody();
        $prenom = trim($body['prenom'] ?? '');
        $nom    = strtoupper(trim($body['nom'] ?? ''));

        if (!$prenom && !$nom) {
            return $this->error($response, 'VALIDATION_ERROR', 'Prénom ou nom requis', 422);
        }

        // Bloquer si commande en cours de gravure
        $commandeEnCours = DB::table('commandes')
            ->where('user_id', $user->id)
            ->whereIn('statut', ['en_lot', 'en_gravure'])
            ->exists();

        if ($commandeEnCours) {
            return $this->error($response, 'NOM_VERROUILLE_COMMANDE_EN_COURS',
                'Impossible de modifier votre nom — une médaille est en cours de gravure avec ce nom.', 422);
        }

        $updates = [];
        if ($prenom) $updates['prenom'] = $prenom;
        if ($nom)    $updates['nom']    = $nom;

        User::where('id', $user->id)->update($updates);

        return $this->success($response, [
            'prenom' => $prenom ?: $user->prenom,
            'nom'    => $nom ?: $user->nom,
        ]);
    }

    public function updatePassword(Request $request, Response $response): Response
    {
        $user = $this->getAuthUser($request);
        if (!$user) return $this->error($response, 'UNAUTHORIZED', 'Non authentifié', 401);

        $body    = (array)$request->getParsedBody();
        $oldPass = trim($body['old_password'] ?? '');
        $newPass = trim($body['new_password'] ?? '');

        if (!$oldPass || !$newPass) {
            return $this->error($response, 'VALIDATION_ERROR', 'Ancien et nouveau mot de passe requis', 400);
        }
        if (strlen($newPass) < 8) {
            return $this->error($response, 'PASSWORD_TOO_SHORT', 'Le mot de passe doit faire au moins 8 caractères', 422);
        }
        if (!$user->password) {
            return $this->error($response, 'NO_LOCAL_PASSWORD',
                'Ce compte utilise uniquement l\'authentification PrestaShop — changez votre mot de passe depuis la boutique.', 422);
        }
        if (!password_verify($oldPass, $user->password)) {
            return $this->error($response, 'INVALID_CREDENTIALS', 'Ancien mot de passe incorrect', 401);
        }

        User::where('id', $user->id)->update([
            'password' => password_hash($newPass, PASSWORD_BCRYPT),
        ]);

        $this->logAudit($user->id, 'password_change', 'user', $user->id, [], $request);

        return $this->success($response, ['message' => 'Mot de passe mis à jour']);
    }

    public function exportData(Request $request, Response $response): Response
    {
        $user = $this->getAuthUser($request);
        if (!$user) return $this->error($response, 'UNAUTHORIZED', 'Non authentifié', 401);

        $chronos   = DB::table('chronos')->where('user_id', $user->id)->get()->toArray();
        $commandes = DB::table('commandes')->where('user_id', $user->id)->get()->toArray();

        $export = [
            'profil'    => [
                'email'           => $user->email,
                'prenom'          => $user->prenom,
                'nom'             => $user->nom,
                'date_inscription'=> $user->date_inscription,
            ],
            'chronos'   => $chronos,
            'commandes' => $commandes,
        ];

        $json = json_encode($export, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
        $response->getBody()->write($json);
        return $response
            ->withHeader('Content-Type', 'application/json')
            ->withHeader('Content-Disposition', 'attachment; filename="mes-donnees-mko.json"');
    }

    public function notifications(Request $request, Response $response): Response
    {
        $user = $this->getAuthUser($request);
        if (!$user) return $this->error($response, 'UNAUTHORIZED', 'Non authentifié', 401);

        $params = $request->getQueryParams();
        $lu     = isset($params['lu']) ? (int)$params['lu'] : null;
        $limit  = min((int)($params['limit'] ?? 50), 100);

        $query = DB::table('notifications')->where('user_id', $user->id);
        if ($lu !== null) $query->where('lu', $lu);
        $items = $query->orderBy('created_at', 'desc')->limit($limit)->get()->toArray();

        return $this->success($response, $items);
    }

    public function marquerNotifLue(Request $request, Response $response, array $args): Response
    {
        $user = $this->getAuthUser($request);
        if (!$user) return $this->error($response, 'UNAUTHORIZED', 'Non authentifié', 401);

        $id   = (int)($args['id'] ?? 0);
        $body = (array)$request->getParsedBody();

        $notif = DB::table('notifications')->where('id', $id)->where('user_id', $user->id)->first();
        if (!$notif) return $this->error($response, 'NOT_FOUND', 'Notification introuvable', 404);

        DB::table('notifications')->where('id', $id)->update(['lu' => (int)($body['lu'] ?? 1)]);

        return $this->success($response, ['message' => 'Notification mise à jour']);
    }

    public function marquerToutLu(Request $request, Response $response): Response
    {
        $user = $this->getAuthUser($request);
        if (!$user) return $this->error($response, 'UNAUTHORIZED', 'Non authentifié', 401);

        DB::table('notifications')->where('user_id', $user->id)->where('lu', 0)->update(['lu' => 1]);

        return $this->success($response, ['message' => 'Toutes les notifications marquées comme lues']);
    }

    public function deleteAccount(Request $request, Response $response): Response
    {
        $user = $this->getAuthUser($request);
        if (!$user) return $this->error($response, 'UNAUTHORIZED', 'Non authentifié', 401);

        $body         = (array)$request->getParsedBody();
        $confirmation = $body['confirmation'] ?? '';
        $caseCochee   = (bool)($body['case_cochee'] ?? false);

        if ($confirmation !== 'SUPPRIMER MON COMPTE') {
            return $this->error($response, 'CONFIRMATION_REQUIRED',
                'Le champ confirmation doit être exactement "SUPPRIMER MON COMPTE"', 400);
        }
        if (!$caseCochee) {
            return $this->error($response, 'CASE_NON_COCHEE',
                'La case de confirmation explicite doit être cochée', 400);
        }

        $commandeEnCours = DB::table('commandes')
            ->where('user_id', $user->id)
            ->whereIn('statut', ['en_lot', 'en_gravure'])
            ->exists();

        if ($commandeEnCours) {
            return $this->error($response, 'COMMANDE_EN_COURS',
                'Impossible de supprimer votre compte — une médaille est en cours de fabrication.', 409);
        }

        // Supprimer aussi coté PrestaShop si le compte y est lié
        if (!empty($user->presta_customer_id)) {
            $this->ps->deleteCustomer((int)$user->presta_customer_id);
        }

        // Anonymiser — JAMAIS supprimer les commandes (obligation légale 10 ans)
        User::where('id', $user->id)->update([
            'email'                => 'anonymized_' . $user->id . '@deleted.mko',
            'prenom'               => null,
            'nom'                  => null,
            'password'             => null,
            'anonymized_at'        => date('Y-m-d H:i:s'),
            'actif'                => 0,
            'strava_connected'     => 0,
            'strava_access_token'  => null,
            'strava_refresh_token' => null,
        ]);

        DB::table('sessions')->where('user_id', $user->id)->delete();

        $this->logAudit($user->id, 'compte_supprime_rgpd', 'user', $user->id, [], $request);

        return $this->success($response, ['message' => 'Données personnelles supprimées. anonymized_at défini.']);
    }
}
