<?php

declare(strict_types=1);

namespace App\Controllers;

use App\Services\StravaService;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;

class StravaController
{
    use ControllerTrait;

    public function __construct(private StravaService $strava) {}

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

        return $this->success($response, ['url' => $this->strava->getAuthUrl($user->id)]);
    }

    public function callback(Request $request, Response $response): Response
    {
        $params = $request->getQueryParams();
        $code   = $params['code'] ?? '';
        $userId = (int)($params['state'] ?? 0);

        if (!$code || !$userId) {
            return $response->withHeader('Location',
                'https://chrono.mykollector.com/strava.html?error=invalid_params')->withStatus(302);
        }

        $ok = $this->strava->exchangeCode($code, $userId);

        $redirect = $ok
            ? 'https://chrono.mykollector.com/strava.html?connected=true'
            : 'https://chrono.mykollector.com/strava.html?error=auth_failed';

        return $response->withHeader('Location', $redirect)->withStatus(302);
    }

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

        if (!$user->strava_connected) {
            return $this->error($response, 'STRAVA_NOT_CONNECTED', 'Compte Strava non connecté', 422);
        }

        $params = $request->getQueryParams();
        $page   = max(1, (int)($params['page'] ?? 1));
        $limit  = min(30, (int)($params['limit'] ?? 10));

        return $this->success($response, $this->strava->getActivites($user->id, $page, $limit));
    }

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

        if (!$user->strava_connected) return $this->success($response, []);

        return $this->success($response, $this->strava->getAlertes($user->id));
    }

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

        try {
            $result = $this->strava->importerActivite($user->id, $args['id']);
            return $this->success($response, $result);
        } catch (\Exception $e) {
            return $this->error($response, 'NOT_FOUND', $e->getMessage(), 404);
        }
    }

    public function webhookVerify(Request $request, Response $response): Response
    {
        $params    = $request->getQueryParams();
        $challenge = $this->strava->verifierWebhook($params);

        if ($challenge === null) {
            return $this->error($response, 'FORBIDDEN', 'Token invalide', 403);
        }

        $response->getBody()->write(json_encode(['hub.challenge' => $challenge]));
        return $response->withHeader('Content-Type', 'application/json');
    }

    public function webhookReceive(Request $request, Response $response): Response
    {
        $body = (array)$request->getParsedBody();

        try {
            $this->strava->traiterWebhook($body);
        } catch (\Exception $e) {
            error_log('[StravaController::webhookReceive] ' . $e->getMessage());
        }

        $response->getBody()->write(json_encode(['status' => 'received']));
        return $response->withHeader('Content-Type', 'application/json');
    }

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

        $this->strava->disconnect($user->id);

        return $this->success($response, ['message' => 'Compte Strava déconnecté']);
    }
}
