<?php

declare(strict_types=1);

namespace App\Controllers;

use App\Repositories\ZonaRepository;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;

class ZonaController
{
    private ZonaRepository $zonas;

    public function __construct(ZonaRepository $zonas)
    {
        $this->zonas = $zonas;
    }

    public function listar(Request $request, Response $response): Response
    {
        return $this->json($response, $this->zonas->todas());
    }

    public function ver(Request $request, Response $response, array $args): Response
    {
        $zona = $this->zonas->buscarPorId((int) $args['id']);

        if (!$zona) {
            return $this->json($response, ['error' => 'Zona no encontrada'], 404);
        }

        return $this->json($response, $zona);
    }

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

        $requeridos = ['nombre', 'centro_lat', 'centro_lng', 'radio_km', 'tarifa_base', 'tarifa_por_km'];
        foreach ($requeridos as $campo) {
            if (!isset($body[$campo]) || $body[$campo] === '') {
                return $this->json($response, ['error' => "El campo {$campo} es requerido"], 422);
            }
        }

        $id = $this->zonas->crear($this->normalizar($body));

        return $this->json($response, $this->zonas->buscarPorId($id), 201);
    }

    public function actualizar(Request $request, Response $response, array $args): Response
    {
        $id = (int) $args['id'];
        if (!$this->zonas->buscarPorId($id)) {
            return $this->json($response, ['error' => 'Zona no encontrada'], 404);
        }

        $body = (array) $request->getParsedBody();
        $this->zonas->actualizar($id, $this->normalizar($body));

        return $this->json($response, $this->zonas->buscarPorId($id));
    }

    public function eliminar(Request $request, Response $response, array $args): Response
    {
        $id = (int) $args['id'];
        if (!$this->zonas->buscarPorId($id)) {
            return $this->json($response, ['error' => 'Zona no encontrada'], 404);
        }

        $this->zonas->eliminar($id);

        return $this->json($response, ['ok' => true]);
    }

    private function normalizar(array $body): array
    {
        return [
            'nombre' => (string) ($body['nombre'] ?? ''),
            'centro_lat' => (float) ($body['centro_lat'] ?? 0),
            'centro_lng' => (float) ($body['centro_lng'] ?? 0),
            'radio_km' => (float) ($body['radio_km'] ?? 0),
            'tarifa_base' => (float) ($body['tarifa_base'] ?? 0),
            'tarifa_por_km' => (float) ($body['tarifa_por_km'] ?? 0),
            'recargo_hora_pico' => (float) ($body['recargo_hora_pico'] ?? 0),
        ];
    }

    private function json(Response $response, $data, int $status = 200): Response
    {
        $response->getBody()->write(json_encode($data));

        return $response->withHeader('Content-Type', 'application/json')->withStatus($status);
    }
}
