<?php

namespace App\Controller;

use Doctrine\DBAL\Connection;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Attribute\Route;

#[Route('/api/forecasts', name: 'api_forecasts_')]
class ForecastController extends AbstractController
{
    public function __construct(private Connection $connection) {}

    /**
     * GET /api/forecasts
     *
     * Paramètres optionnels :
     *   ?bbox=minLon,minLat,maxLon,maxLat   filtre spatial PostGIS
     *   ?horizon=6                           filtre sur time_horizon (6, 12, 24, 48)
     */
    #[Route('', name: 'collection', methods: ['GET'])]
    public function collection(Request $request): JsonResponse
    {
        $sql = <<<SQL
            SELECT
                f.id,
                f.time_horizon      AS "timeHorizon",
                f.valid_at          AS "validAt",
                f.computed_at       AS "computedAt",
                f.model_version     AS "modelVersion",
                f.confidence,
                f.source_observation_id AS "sourceObservationId",
                ST_AsGeoJSON(f.geometry)::json AS geometry
            FROM sargassum_forecast f
            WHERE 1=1
        SQL;

        $params = [];

        $bboxParam = $request->query->get('bbox');
        if ($bboxParam !== null) {
            $parts = array_map('floatval', explode(',', $bboxParam));
            if (count($parts) === 4) {
                [$minLon, $minLat, $maxLon, $maxLat] = $parts;
                $sql .= ' AND ST_Intersects(f.geometry, ST_MakeEnvelope(:minLon, :minLat, :maxLon, :maxLat, 4326))';
                $params['minLon'] = $minLon;
                $params['minLat'] = $minLat;
                $params['maxLon'] = $maxLon;
                $params['maxLat'] = $maxLat;
            }
        }

        $horizonParam = $request->query->get('horizon');
        if ($horizonParam !== null && in_array((int) $horizonParam, [6, 12, 24, 48], true)) {
            $sql .= ' AND f.time_horizon = :horizon';
            $params['horizon'] = (int) $horizonParam;
        }

        $sql .= ' ORDER BY f.valid_at DESC LIMIT 50';

        $rows = $this->connection->fetchAllAssociative($sql, $params);

        foreach ($rows as &$row) {
            $row['geometry'] = $row['geometry'] ? json_decode($row['geometry'], true) : null;
        }

        return $this->json(['items' => $rows, 'total' => count($rows)]);
    }

    /**
     * GET /api/forecasts/{id}
     */
    #[Route('/{id}', name: 'item', methods: ['GET'])]
    public function item(string $id): JsonResponse
    {
        $row = $this->connection->fetchAssociative(
            'SELECT f.id, f.time_horizon AS "timeHorizon", f.valid_at AS "validAt",
                    f.computed_at AS "computedAt", f.model_version AS "modelVersion",
                    f.confidence, f.source_observation_id AS "sourceObservationId",
                    ST_AsGeoJSON(f.geometry)::json AS geometry
             FROM sargassum_forecast f WHERE f.id = :id',
            ['id' => $id]
        );

        if ($row === false) {
            return $this->json(['error' => 'Forecast not found'], 404);
        }

        $row['geometry'] = $row['geometry'] ? json_decode($row['geometry'], true) : null;

        return $this->json($row);
    }
}
