<?php

declare(strict_types=1);

namespace App\Repositories;

use PDO;

class PedidoRepository
{
    public const ESTADOS_VALIDOS = ['creado', 'recoleccion', 'transito', 'entrega', 'cerrado', 'cancelado'];

    private PDO $db;

    public function __construct(PDO $db)
    {
        $this->db = $db;
    }

    public function crear(array $datos): int
    {
        $stmt = $this->db->prepare(
            'INSERT INTO pedidos
                (tienda_id, cliente_nombre, cliente_telefono,
                 direccion_origen, origen_lat, origen_lng,
                 direccion_destino, destino_lat, destino_lng,
                 costo_envio, estado, token_publico, created_at)
             VALUES
                (:tienda_id, :cliente_nombre, :cliente_telefono,
                 :direccion_origen, :origen_lat, :origen_lng,
                 :direccion_destino, :destino_lat, :destino_lng,
                 :costo_envio, "creado", :token_publico, NOW())'
        );
        $datos['token_publico'] = bin2hex(random_bytes(16));
        $stmt->execute($datos);

        return (int) $this->db->lastInsertId();
    }

    public function buscarPorId(int $id): ?array
    {
        $stmt = $this->db->prepare('SELECT * FROM pedidos WHERE id = :id');
        $stmt->execute(['id' => $id]);
        $pedido = $stmt->fetch();

        return $pedido ?: null;
    }

    public function buscarPorIdYToken(int $id, string $token): ?array
    {
        $stmt = $this->db->prepare('SELECT * FROM pedidos WHERE id = :id AND token_publico = :token');
        $stmt->execute(['id' => $id, 'token' => $token]);
        $pedido = $stmt->fetch();

        return $pedido ?: null;
    }

    public function listarPorFiltro(array $filtros): array
    {
        $sql = 'SELECT * FROM pedidos WHERE 1=1';
        $params = [];

        if (!empty($filtros['estado'])) {
            $sql .= ' AND estado = :estado';
            $params['estado'] = $filtros['estado'];
        }
        if (!empty($filtros['tienda_id'])) {
            $sql .= ' AND tienda_id = :tienda_id';
            $params['tienda_id'] = $filtros['tienda_id'];
        }
        if (!empty($filtros['repartidor_id'])) {
            $sql .= ' AND repartidor_id = :repartidor_id';
            $params['repartidor_id'] = $filtros['repartidor_id'];
        }

        $sql .= ' ORDER BY created_at DESC LIMIT 100';

        $stmt = $this->db->prepare($sql);
        $stmt->execute($params);

        return $stmt->fetchAll();
    }

    public function asignarRepartidor(int $pedidoId, int $repartidorId): void
    {
        $stmt = $this->db->prepare('UPDATE pedidos SET repartidor_id = :repartidor_id WHERE id = :id');
        $stmt->execute(['repartidor_id' => $repartidorId, 'id' => $pedidoId]);
    }

    public function cambiarEstado(int $pedidoId, string $estadoNuevo): void
    {
        $columnaTimestamp = [
            'recoleccion' => 'recolectado_at',
            'transito' => 'transito_at',
            'entrega' => 'entregado_at',
            'cerrado' => 'cerrado_at',
            'cancelado' => 'cancelado_at',
        ][$estadoNuevo] ?? null;

        $sql = 'UPDATE pedidos SET estado = :estado';
        if ($columnaTimestamp) {
            $sql .= ", {$columnaTimestamp} = NOW()";
        }
        $sql .= ' WHERE id = :id';

        $stmt = $this->db->prepare($sql);
        $stmt->execute(['estado' => $estadoNuevo, 'id' => $pedidoId]);
    }
}
