<?php
declare(strict_types=1);

const INDICACAO_MIN_RETIRADA = 25.00;

function indicacoes_usuario_base(int $idUsuario): ?array
{
    $stmt = db()->prepare(
        'SELECT id, nome, tipo, codigoind, indicador_codigo, criado_em,
                banco_nome, banco_agencia, banco_conta, banco_tipo_conta,
                banco_titular_nome, banco_titular_documento, pix_tipo, pix_chave
         FROM usuarios
         WHERE id = ?
         LIMIT 1'
    );
    $stmt->execute([$idUsuario]);
    $usuario = $stmt->fetch();

    return $usuario ?: null;
}

function indicacoes_conta_completa(array $usuario): bool
{
    $titularOk = trim((string) ($usuario['banco_titular_nome'] ?? '')) !== ''
        && trim((string) ($usuario['banco_titular_documento'] ?? '')) !== '';
    $pixOk = trim((string) ($usuario['pix_chave'] ?? '')) !== '';
    $bancoOk = trim((string) ($usuario['banco_nome'] ?? '')) !== ''
        && trim((string) ($usuario['banco_agencia'] ?? '')) !== ''
        && trim((string) ($usuario['banco_conta'] ?? '')) !== '';

    return $titularOk && ($pixOk || $bancoOk);
}

function indicacoes_total_gerado(string $codigo): float
{
    if (trim($codigo) === '') {
        return 0.0;
    }

    $stmt = db()->prepare(
        'SELECT COALESCE(SUM(valor_indicacao), 0) AS total
         FROM (
            SELECT COALESCE(c.valor, 0) * 0.025 AS valor_indicacao
            FROM corridas c
            INNER JOIN usuarios m ON m.id = c.id_motorista
            INNER JOIN usuarios im ON im.codigoind = m.indicador_codigo AND im.tipo = "motorista"
            WHERE c.status = "finalizada"
              AND m.indicador_codigo = ?
            UNION ALL
            SELECT COALESCE(c.valor, 0) * 0.015 AS valor_indicacao
            FROM corridas c
            INNER JOIN usuarios p ON p.id = c.id_passageiro
            INNER JOIN usuarios ip ON ip.codigoind = p.indicador_codigo
            WHERE c.status = "finalizada"
              AND p.indicador_codigo = ?
         ) repasses'
    );
    $stmt->execute([$codigo, $codigo]);

    return round((float) $stmt->fetchColumn(), 2);
}

function indicacoes_totais_retiradas(int $idUsuario): array
{
    $stmt = db()->prepare(
        'SELECT
            COALESCE(SUM(CASE WHEN status = "paga" THEN valor ELSE 0 END), 0) AS pago,
            COALESCE(SUM(CASE WHEN status IN ("pendente", "em_processamento") THEN valor ELSE 0 END), 0) AS bloqueado
         FROM indicacao_retiradas
         WHERE id_usuario = ?'
    );
    $stmt->execute([$idUsuario]);
    $row = $stmt->fetch() ?: ['pago' => 0, 'bloqueado' => 0];

    return [
        'pago' => round((float) ($row['pago'] ?? 0), 2),
        'bloqueado' => round((float) ($row['bloqueado'] ?? 0), 2),
    ];
}

function indicacoes_resumo_usuario(int $idUsuario): array
{
    $usuario = indicacoes_usuario_base($idUsuario);
    if (!$usuario) {
        return [
            'total_gerado' => 0.0,
            'total_pago' => 0.0,
            'total_bloqueado' => 0.0,
            'saldo_disponivel' => 0.0,
            'minimo_retirada' => INDICACAO_MIN_RETIRADA,
            'conta_completa' => false,
        ];
    }

    $totalGerado = indicacoes_total_gerado((string) $usuario['codigoind']);
    $retiradas = indicacoes_totais_retiradas($idUsuario);
    $saldo = max(0, $totalGerado - $retiradas['pago'] - $retiradas['bloqueado']);

    return [
        'total_gerado' => round($totalGerado, 2),
        'total_pago' => round($retiradas['pago'], 2),
        'total_bloqueado' => round($retiradas['bloqueado'], 2),
        'saldo_disponivel' => round($saldo, 2),
        'minimo_retirada' => INDICACAO_MIN_RETIRADA,
        'conta_completa' => indicacoes_conta_completa($usuario),
    ];
}

function indicacoes_extrato_usuario(int $idUsuario, int $limit = 80): array
{
    $usuario = indicacoes_usuario_base($idUsuario);
    if (!$usuario || trim((string) $usuario['codigoind']) === '') {
        return [];
    }

    $limit = max(1, min(200, $limit));
    $codigo = (string) $usuario['codigoind'];
    $stmt = db()->prepare(
        'SELECT *
         FROM (
            SELECT
                c.id AS id_corrida,
                COALESCE(c.finalizada_em, c.atualizada_em, c.criada_em) AS data_evento,
                "motorista" AS origem,
                m.nome AS indicado_nome,
                m.tipo AS indicado_tipo,
                COALESCE(c.valor, 0) AS valor_corrida,
                COALESCE(c.valor, 0) * 0.025 AS valor_indicacao
            FROM corridas c
            INNER JOIN usuarios m ON m.id = c.id_motorista
            INNER JOIN usuarios im ON im.codigoind = m.indicador_codigo AND im.tipo = "motorista"
            WHERE c.status = "finalizada"
              AND m.indicador_codigo = ?
            UNION ALL
            SELECT
                c.id AS id_corrida,
                COALESCE(c.finalizada_em, c.atualizada_em, c.criada_em) AS data_evento,
                "passageiro" AS origem,
                p.nome AS indicado_nome,
                p.tipo AS indicado_tipo,
                COALESCE(c.valor, 0) AS valor_corrida,
                COALESCE(c.valor, 0) * 0.015 AS valor_indicacao
            FROM corridas c
            INNER JOIN usuarios p ON p.id = c.id_passageiro
            INNER JOIN usuarios ip ON ip.codigoind = p.indicador_codigo
            WHERE c.status = "finalizada"
              AND p.indicador_codigo = ?
         ) extrato
         ORDER BY data_evento DESC
         LIMIT ' . $limit
    );
    $stmt->execute([$codigo, $codigo]);

    $rows = [];
    foreach ($stmt->fetchAll() as $row) {
        $row['id_corrida'] = (int) $row['id_corrida'];
        $row['valor_corrida'] = round((float) $row['valor_corrida'], 2);
        $row['valor_indicacao'] = round((float) $row['valor_indicacao'], 2);
        $rows[] = $row;
    }

    return $rows;
}

function indicacoes_retiradas_usuario(int $idUsuario, int $limit = 50): array
{
    $limit = max(1, min(120, $limit));
    $stmt = db()->prepare(
        'SELECT id, valor, saldo_no_pedido, status, pix_tipo, pix_chave, banco_nome, banco_agencia, banco_conta,
                banco_tipo_conta, banco_titular_nome, banco_titular_documento, prazo_limite,
                observacao, solicitado_em, processado_por, processado_em
         FROM indicacao_retiradas
         WHERE id_usuario = ?
         ORDER BY solicitado_em DESC
         LIMIT ' . $limit
    );
    $stmt->execute([$idUsuario]);

    $rows = [];
    foreach ($stmt->fetchAll() as $row) {
        $row['id'] = (int) $row['id'];
        $row['valor'] = round((float) $row['valor'], 2);
        $row['saldo_no_pedido'] = round((float) ($row['saldo_no_pedido'] ?? 0), 2);
        $rows[] = $row;
    }

    return $rows;
}

function indicacoes_adicionar_dias_uteis(DateTimeImmutable $data, int $dias): DateTimeImmutable
{
    $cursor = $data;
    $adicionados = 0;
    while ($adicionados < $dias) {
        $cursor = $cursor->modify('+1 day');
        $diaSemana = (int) $cursor->format('N');
        if ($diaSemana <= 5) {
            $adicionados++;
        }
    }

    return $cursor;
}
