<?php
include_once __DIR__ . '/../services/pdo_connection.php';
require_once __DIR__ . '/../services/PedidoEstadoHelper.php';

class Pedido
{
    private $conn;

    public function __construct()
    {
        $database = new Database();
        $this->conn = $database->getConnection();
    }

    public function createPedido($data)
    {
        $metodoPago = $data['metodo_pago'] ?? 'cash';
        $estadoPago = $data['estado_pago'] ?? PedidoEstadoHelper::estadoPagoInicial($metodoPago);
        $estadoEntrega = $data['estado_entrega'] ?? 'PENDIENTE';
        $estadoLegacy = PedidoEstadoHelper::syncLegacyEstado($estadoPago, $estadoEntrega);

        $query = "INSERT INTO pedido (
                      nombre_cliente, telefono, direccion_texto, referencia,
                      monto_total, costo_envio_aplicado, subtotal_productos,
                      estado, estado_pago, estado_entrega,
                      mercado_pago_pref_id, mercado_pago_payment_id, fecha_pedido,
                      envio_dom, latitud, longitud, metodo_pago, whatsapp_enviado
                  ) VALUES (
                      :nombre_cliente, :telefono, :direccion_texto, :referencia,
                      :monto_total, :costo_envio_aplicado, :subtotal_productos,
                      :estado, :estado_pago, :estado_entrega,
                      :mercado_pago_pref_id, :mercado_pago_payment_id, :fecha_pedido,
                      :envio_dom, :latitud, :longitud, :metodo_pago, 0
                  )";

        $stmt = $this->conn->prepare($query);

        $nombreCliente = $data['nombre_cliente'] ?? '';
        $telefono = $data['telefono'] ?? '';
        $direccionTexto = $data['direccion_texto'] ?? null;
        $referencia = $data['referencia'] ?? null;
        $montoTotal = (float)($data['monto_total'] ?? 0);
        $costoEnvio = (float)($data['costo_envio_aplicado'] ?? 0);
        $subtotal = (float)($data['subtotal_productos'] ?? $montoTotal);
        $mercadoPagoPrefId = $data['mercado_pago_pref_id'] ?? null;
        $mercadoPagoPaymentId = $data['mercado_pago_payment_id'] ?? null;
        $fechaPedido = $data['fecha_pedido'] ?? date('Y-m-d H:i:s');
        $envioDom = isset($data['envio_dom']) ? (int)$data['envio_dom'] : 0;
        $latitud = $data['latitud'] ?? null;
        $longitud = $data['longitud'] ?? null;

        $stmt->bindValue(':nombre_cliente', $nombreCliente, PDO::PARAM_STR);
        $stmt->bindValue(':telefono', $telefono, PDO::PARAM_STR);
        $stmt->bindValue(':direccion_texto', $direccionTexto, PDO::PARAM_STR);
        $stmt->bindValue(':referencia', $referencia, PDO::PARAM_STR);
        $stmt->bindValue(':monto_total', $montoTotal);
        $stmt->bindValue(':costo_envio_aplicado', $costoEnvio);
        $stmt->bindValue(':subtotal_productos', $subtotal);
        $stmt->bindValue(':estado', $estadoLegacy, PDO::PARAM_STR);
        $stmt->bindValue(':estado_pago', $estadoPago, PDO::PARAM_STR);
        $stmt->bindValue(':estado_entrega', $estadoEntrega, PDO::PARAM_STR);
        $stmt->bindValue(':mercado_pago_pref_id', $mercadoPagoPrefId, PDO::PARAM_STR);
        $stmt->bindValue(':mercado_pago_payment_id', $mercadoPagoPaymentId, PDO::PARAM_STR);
        $stmt->bindValue(':fecha_pedido', $fechaPedido, PDO::PARAM_STR);
        $stmt->bindValue(':envio_dom', $envioDom, PDO::PARAM_INT);
        $stmt->bindValue(':latitud', $latitud, PDO::PARAM_STR);
        $stmt->bindValue(':longitud', $longitud, PDO::PARAM_STR);
        $stmt->bindValue(':metodo_pago', $metodoPago, PDO::PARAM_STR);

        if ($stmt->execute()) {
            return (int)$this->conn->lastInsertId();
        }
        return false;
    }

    public function getPedidoById($id)
    {
        $stmt = $this->conn->prepare('SELECT * FROM pedido WHERE id_pedido = :id');
        $stmt->bindValue(':id', (int)$id, PDO::PARAM_INT);
        $stmt->execute();
        return $stmt->fetch(PDO::FETCH_ASSOC);
    }

    public function getAllPedidos()
    {
        $stmt = $this->conn->query('SELECT * FROM pedido ORDER BY fecha_pedido DESC');
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }

    public function updateEstados(int $idPedido, ?string $estadoPago, ?string $estadoEntrega): bool
    {
        $pedido = $this->getPedidoById($idPedido);
        if (!$pedido) {
            return false;
        }

        $pago = $estadoPago ?? $pedido['estado_pago'] ?? 'PENDIENTE';
        $entrega = $estadoEntrega ?? $pedido['estado_entrega'] ?? 'PENDIENTE';
        $legacy = PedidoEstadoHelper::syncLegacyEstado($pago, $entrega);

        $sql = 'UPDATE pedido SET estado_pago = :pago, estado_entrega = :entrega, estado = :legacy WHERE id_pedido = :id';
        $stmt = $this->conn->prepare($sql);
        return $stmt->execute([
            ':pago' => $pago,
            ':entrega' => $entrega,
            ':legacy' => $legacy,
            ':id' => $idPedido,
        ]);
    }

    /** @deprecated Use updateEstados */
    public function updateEstadoPedido($idPedido, $estado)
    {
        $entrega = in_array($estado, ['ENTREGADO', 'CANCELADO'], true) ? $estado : 'PENDIENTE';
        $pago = $estado === 'PAGADO' ? 'PAGADO' : null;
        if ($estado === 'CANCELADO') {
            $pago = 'RECHAZADO';
        }
        return $this->updateEstados((int)$idPedido, $pago, $entrega);
    }

    public function aplicarEstadoMercadoPago(int $idPedido, string $mpStatus, ?string $paymentId = null): bool
    {
        $map = PedidoEstadoHelper::mapMercadoPagoStatus($mpStatus);
        $legacy = PedidoEstadoHelper::syncLegacyEstado($map['estado_pago'], $map['estado_entrega']);

        $sql = 'UPDATE pedido SET
            estado_pago = :pago, estado_entrega = :entrega, estado = :legacy,
            mercado_pago_payment_id = COALESCE(:payment_id, mercado_pago_payment_id)
            WHERE id_pedido = :id';
        $stmt = $this->conn->prepare($sql);
        return $stmt->execute([
            ':pago' => $map['estado_pago'],
            ':entrega' => $map['estado_entrega'],
            ':legacy' => $legacy,
            ':payment_id' => $paymentId,
            ':id' => $idPedido,
        ]);
    }

    public function marcarWhatsappEnviado(int $idPedido): bool
    {
        $stmt = $this->conn->prepare(
            'UPDATE pedido SET whatsapp_enviado = 1, whatsapp_enviado_en = NOW() WHERE id_pedido = :id'
        );
        return $stmt->execute([':id' => $idPedido]);
    }

    public function updateCoordenadas($idPedido, $latitud, $longitud)
    {
        $stmt = $this->conn->prepare(
            'UPDATE pedido SET latitud = :latitud, longitud = :longitud WHERE id_pedido = :id'
        );
        return $stmt->execute([
            ':latitud' => $latitud,
            ':longitud' => $longitud,
            ':id' => (int)$idPedido,
        ]);
    }

    public function updatePedidoMercadoPagoId($idPedido, $preferenceId)
    {
        $stmt = $this->conn->prepare(
            "UPDATE pedido SET mercado_pago_pref_id = :preferenceId, metodo_pago = 'mercadopago' WHERE id_pedido = :id"
        );
        return $stmt->execute([':preferenceId' => $preferenceId, ':id' => (int)$idPedido]);
    }

    public function getPedidoByPaymentId(string $paymentId)
    {
        $stmt = $this->conn->prepare(
            'SELECT * FROM pedido WHERE mercado_pago_payment_id = :pid LIMIT 1'
        );
        $stmt->execute([':pid' => $paymentId]);
        return $stmt->fetch(PDO::FETCH_ASSOC);
    }

    public function getPedidoByExternalReference($ref)
    {
        $id = (int)$ref;
        if ($id <= 0) {
            return false;
        }
        return $this->getPedidoById($id);
    }

    // Legacy object API
    private $id_pedido;
    private $estado;

    public function setIdPedido($id) { $this->id_pedido = $id; }
    public function setEstado($estado) { $this->estado = $estado; }

    public function actualizarEstado($db)
    {
        $entrega = $this->estado;
        if (!in_array($entrega, ['PENDIENTE', 'EN_PREPARACION', 'EN_CAMINO', 'ENTREGADO', 'CANCELADO'], true)) {
            $entrega = $this->estado === 'ENTREGADO' ? 'ENTREGADO'
                : ($this->estado === 'CANCELADO' ? 'CANCELADO' : 'PENDIENTE');
        }
        return $this->updateEstados((int)$this->id_pedido, null, $entrega);
    }
}
