<?php
declare(strict_types=1);

namespace App\Modules\PlayerApi\Controllers\Api;

use App\Core\ApiController;
use App\Core\Request;
use App\Core\Response;
use App\Core\App;

final class FinancialController extends ApiController
{
    public function summary(Request $request): Response
    {
        $player = App::getInstance()->currentPlayer();
        $db = App::getInstance()->db();
        $playerId = (int) $player->id;
        $memberId = $player->member_id ? (int) $player->member_id : null;

        $subscriptionsDue = $db->selectOne(
            "SELECT COALESCE(SUM(total_amount), 0) as total
             FROM activity_subscriptions
             WHERE player_id = ? AND status IN ('pending', 'overdue')",
            [$playerId]
        );

        $nextDue = $db->selectOne(
            "SELECT due_date, total_amount, subscription_month
             FROM activity_subscriptions
             WHERE player_id = ? AND status = 'pending'
             ORDER BY due_date ASC LIMIT 1",
            [$playerId]
        );

        $totalPaid = $db->selectOne(
            "SELECT COALESCE(SUM(amount), 0) as total
             FROM payments
             WHERE player_id = ? AND is_voided = 0",
            [$playerId]
        );

        $finesDue = '0.00';
        if ($memberId) {
            $finesRow = $db->selectOne(
                "SELECT COALESCE(SUM(amount - paid_amount), 0) as total
                 FROM fines WHERE member_id = ? AND status IN ('imposed', 'appeal_upheld')",
                [$memberId]
            );
            $finesDue = $finesRow['total'] ?? '0.00';
        }

        return $this->successResponse([
            'subscriptions_due' => $subscriptionsDue['total'] ?? '0.00',
            'fines_due' => $finesDue,
            'total_paid' => $totalPaid['total'] ?? '0.00',
            'next_due' => $nextDue ? [
                'date' => $nextDue['due_date'],
                'amount' => $nextDue['total_amount'],
                'month' => $nextDue['subscription_month'],
            ] : null,
        ]);
    }

    public function subscriptions(Request $request): Response
    {
        $player = App::getInstance()->currentPlayer();
        $db = App::getInstance()->db();

        $page = max(1, (int) ($request->get('page') ?? 1));
        $perPage = 12;
        $offset = ($page - 1) * $perPage;

        $total = (int) ($db->selectOne(
            "SELECT COUNT(*) as cnt FROM activity_subscriptions WHERE player_id = ?",
            [(int) $player->id]
        )['cnt'] ?? 0);

        $rows = $db->select(
            "SELECT subscription_month, base_rate, applied_rate, discount, total_amount,
                    status, due_date, paid_at
             FROM activity_subscriptions
             WHERE player_id = ?
             ORDER BY subscription_month DESC
             LIMIT ? OFFSET ?",
            [(int) $player->id, $perPage, $offset]
        );

        return $this->paginatedResponse($rows, $total, $page, $perPage);
    }

    public function payments(Request $request): Response
    {
        $player = App::getInstance()->currentPlayer();
        $db = App::getInstance()->db();

        $page = max(1, (int) ($request->get('page') ?? 1));
        $perPage = 20;
        $offset = ($page - 1) * $perPage;

        $memberId = $player->member_id ? (int) $player->member_id : null;
        $playerId = (int) $player->id;

        $whereClause = $memberId
            ? "(p.member_id = ? OR p.player_id = ?) AND p.is_voided = 0"
            : "p.player_id = ? AND p.is_voided = 0";
        $params = $memberId ? [$memberId, $playerId] : [$playerId];

        $total = (int) ($db->selectOne(
            "SELECT COUNT(*) as cnt FROM payments p WHERE {$whereClause}",
            $params
        )['cnt'] ?? 0);

        $rows = $db->select(
            "SELECT p.payment_type, p.amount, p.payment_method, p.payment_date, p.currency
             FROM payments p
             WHERE {$whereClause}
             ORDER BY p.payment_date DESC
             LIMIT ? OFFSET ?",
            array_merge($params, [$perPage, $offset])
        );

        return $this->paginatedResponse($rows, $total, $page, $perPage);
    }

    public function fines(Request $request): Response
    {
        $player = App::getInstance()->currentPlayer();
        $db = App::getInstance()->db();

        if (!$player->member_id) {
            return $this->successResponse([]);
        }

        $fines = $db->select(
            "SELECT fine_type, amount, paid_amount, penalty_type, status,
                    suspension_from, suspension_to, appeal_submitted, appeal_decision, created_at
             FROM fines
             WHERE member_id = ? AND status IN ('imposed', 'appeal_upheld')
             ORDER BY created_at DESC LIMIT 20",
            [(int) $player->member_id]
        );

        return $this->successResponse($fines);
    }

    public function installments(Request $request): Response
    {
        $player = App::getInstance()->currentPlayer();
        $db = App::getInstance()->db();

        if (!$player->member_id) {
            return $this->successResponse(null);
        }

        $plan = $db->selectOne(
            "SELECT * FROM installment_plans WHERE member_id = ? AND status = 'active' LIMIT 1",
            [(int) $player->member_id]
        );

        if (!$plan) {
            return $this->successResponse(null);
        }

        $schedule = $db->select(
            "SELECT installment_number, due_date, amount, paid_amount, status, paid_at
             FROM installment_schedule
             WHERE installment_plan_id = ?
             ORDER BY installment_number ASC",
            [(int) $plan['id']]
        );

        return $this->successResponse([
            'total_amount' => $plan['total_amount'],
            'down_payment' => $plan['down_payment'],
            'remaining_balance' => $plan['remaining_balance'],
            'monthly_payment' => $plan['monthly_payment'],
            'number_of_months' => (int) $plan['number_of_months'],
            'start_date' => $plan['start_date'],
            'status' => $plan['status'],
            'schedule' => $schedule,
        ]);
    }
}
