<?php
declare(strict_types=1);

require_once __DIR__ . '/../config/helpers.php';

$data = input_json();
require_fields($data, ['id_corrida', 'id_passageiro', 'nota']);

$idCorrida = (int) $data['id_corrida'];
$idPassageiro = (int) $data['id_passageiro'];
$nota = (int) $data['nota'];
$comentario = trim((string) ($data['comentario'] ?? ''));
$selo = trim((string) ($data['selo'] ?? ''));
$problemas = $data['problemas'] ?? [];

if ($idCorrida <= 0 || $idPassageiro <= 0) {
    json_fail('Dados invalidos para avaliar corrida.');
}

if ($nota < 1 || $nota > 5) {
    json_fail('A nota deve ser entre 1 e 5.');
}

if (!is_array($problemas)) {
    $problemas = [];
}

$selosValidos = ['bom_condutor', 'simpatico', 'veiculo_limpo', 'boa_rota', 'boa_conversa'];
if (!in_array($selo, $selosValidos, true)) {
    $selo = '';
}

$problemasLabels = [
    'problema_veiculo' => 'Problema no veiculo',
    'veiculo_sujo' => 'Veiculo sujo',
    'motorista_rude' => 'Motorista rude',
    'direcao_perigosa' => 'Direcao perigosa',
    'rota_ruim' => 'Rota ruim',
    'atraso' => 'Atraso excessivo',
    'outro' => 'Outro',
];

$problemasSelecionados = [];
foreach ($problemas as $problema) {
    $chave = (string) $problema;
    if (isset($problemasLabels[$chave])) {
        $problemasSelecionados[$chave] = $problemasLabels[$chave];
    }
}

if ($nota < 5 && $comentario === '' && empty($problemasSelecionados)) {
    json_fail('Informe pelo menos um motivo para a avaliacao.');
}

try {
    $pdo = db();
    $pdo->beginTransaction();

    $stmt = $pdo->prepare(
        'SELECT id, id_passageiro, id_motorista, status, avaliacao_motorista
         FROM corridas
         WHERE id = ?
         LIMIT 1
         FOR UPDATE'
    );
    $stmt->execute([$idCorrida]);
    $corrida = $stmt->fetch();

    if (!$corrida) {
        $pdo->rollBack();
        json_fail('Corrida nao encontrada.', 404);
    }

    if ((int) $corrida['id_passageiro'] !== $idPassageiro) {
        $pdo->rollBack();
        json_fail('Essa corrida nao pertence a este passageiro.', 403);
    }

    if (($corrida['status'] ?? '') !== 'finalizada') {
        $pdo->rollBack();
        json_fail('A corrida ainda nao foi finalizada.', 409);
    }

    $idMotorista = (int) ($corrida['id_motorista'] ?? 0);
    if ($idMotorista <= 0) {
        $pdo->rollBack();
        json_fail('Motorista nao encontrado para esta corrida.', 409);
    }

    if ($corrida['avaliacao_motorista'] !== null) {
        $pdo->commit();
        json_ok(['already_avaliada' => true]);
    }

    $up = $pdo->prepare(
        'UPDATE corridas
         SET avaliacao_motorista = ?,
             avaliacao_comentario = ?,
             avaliado_em = NOW()
         WHERE id = ?'
    );
    $up->execute([$nota, $comentario === '' ? null : $comentario, $idCorrida]);

    $delElogio = $pdo->prepare(
        'DELETE FROM motorista_elogios
         WHERE id_corrida = ? AND id_passageiro = ?'
    );
    $delElogio->execute([$idCorrida, $idPassageiro]);

    if ($nota === 5 && $selo !== '') {
        $elogio = $pdo->prepare(
            'INSERT INTO motorista_elogios (id_motorista, id_passageiro, id_corrida, selo)
             VALUES (?, ?, ?, ?)'
        );
        $elogio->execute([$idMotorista, $idPassageiro, $idCorrida, $selo]);
    }

    if ($nota < 5) {
        $partes = [];
        if (!empty($problemasSelecionados)) {
            $partes[] = 'Motivos: ' . implode(', ', array_values($problemasSelecionados)) . '.';
        }
        if ($comentario !== '') {
            $partes[] = 'Comentario: ' . $comentario;
        }
        $textoFeedback = trim(implode(' ', $partes));
        if ($textoFeedback === '') {
            $textoFeedback = 'Avaliacao negativa sem comentario.';
        }

        $feedback = $pdo->prepare(
            'INSERT INTO usuario_feedbacks
                (id_usuario, id_corrida, tipo, origem, nota, comentario, registrado_por)
             VALUES (?, ?, "reclamacao", "passageiro", ?, ?, ?)'
        );
        $feedback->execute([
            $idMotorista,
            $idCorrida,
            $nota,
            $textoFeedback,
            'passageiro:' . $idPassageiro,
        ]);
    }

    $pdo->commit();
    json_ok(['avaliada' => true]);
} catch (Throwable $e) {
    if (isset($pdo) && $pdo->inTransaction()) {
        $pdo->rollBack();
    }
    json_fail('Erro ao salvar avaliacao.', 500, ['error' => $e->getMessage()]);
}
