<?php
declare(strict_types=1);

namespace App\Modules\SportsActivity\Controllers\Api;

use App\Core\Controller;
use App\Core\Request;
use App\Core\Response;
use App\Core\App;
use App\Modules\SportsActivity\SaConstants;

class SubscriptionPreviewApiController extends Controller
{
    public function preview(Request $request): Response
    {
        $yearMonth = $request->get('month', date('Y-m', strtotime('+1 month')));
        if (!preg_match('/^\d{4}-\d{2}$/', $yearMonth)) {
            return $this->json(['success' => false, 'error' => 'صيغة الشهر غير صالحة']);
        }

        $db = App::getInstance()->db();
        $periodStart = $yearMonth . '-01';

        $groupPlayers = $db->select(
            "SELECT gp.player_id, gp.group_id, gp.enrolled_at, gp.paused_months,
                    sp.player_type, sp.full_name_ar as player_name,
                    p.monthly_fee_member, p.monthly_fee_nonmember, g.name_ar as group_name
             FROM sa_group_players gp
             JOIN sa_players sp ON sp.id = gp.player_id
             JOIN sa_groups g ON g.id = gp.group_id
             JOIN sa_programs p ON p.id = g.program_id
             WHERE gp.status = ?
               AND g.status = ? AND g.is_archived = 0",
            [SaConstants::STATUS_ACTIVE, SaConstants::GROUP_ACTIVE]
        );

        $existingSubs = $db->select(
            "SELECT player_id, group_id FROM sa_subscriptions WHERE period_start = ?",
            [$periodStart]
        );
        $existingSet = [];
        foreach ($existingSubs as $es) {
            $existingSet[$es['player_id'] . ':' . $es['group_id']] = true;
        }

        $items = [];
        $exceptions = [];
        $totalAmount = 0.0;

        foreach ($groupPlayers as $gp) {
            $key = $gp['player_id'] . ':' . $gp['group_id'];

            if (isset($existingSet[$key])) {
                $exceptions[] = [
                    'player_name' => $gp['player_name'],
                    'group_name'  => $gp['group_name'],
                    'reason'      => 'اشتراك موجود بالفعل',
                ];
                continue;
            }

            $pausedMonths = json_decode($gp['paused_months'] ?? '[]', true) ?: [];
            if (in_array($yearMonth, $pausedMonths, true)) {
                $exceptions[] = [
                    'player_name' => $gp['player_name'],
                    'group_name'  => $gp['group_name'],
                    'reason'      => 'مؤجل',
                ];
                continue;
            }

            $amount = $gp['player_type'] === SaConstants::PLAYER_MEMBER
                ? (float) $gp['monthly_fee_member']
                : (float) $gp['monthly_fee_nonmember'];

            $isFirstMonth = !$db->selectOne(
                "SELECT id FROM sa_subscriptions WHERE player_id = ? AND group_id = ? AND period_start < ? LIMIT 1",
                [(int) $gp['player_id'], (int) $gp['group_id'], $periodStart]
            );

            $prorated = false;
            if ($isFirstMonth && !empty($gp['enrolled_at'])) {
                $enrollmentDay = (int) date('j', strtotime($gp['enrolled_at']));
                if ($enrollmentDay > 15) {
                    $amount = round($amount / 2, 2);
                    $prorated = true;
                }
            }

            $items[] = [
                'player_id'   => (int) $gp['player_id'],
                'player_name' => $gp['player_name'],
                'group_id'    => (int) $gp['group_id'],
                'group_name'  => $gp['group_name'],
                'amount'      => $amount,
                'prorated'    => $prorated,
                'paused'      => false,
            ];

            $totalAmount += $amount;
        }

        return $this->json([
            'success'      => true,
            'month'        => $yearMonth,
            'items'        => $items,
            'total_amount' => $totalAmount,
            'count'        => count($items),
            'exceptions'   => $exceptions,
        ]);
    }

    public function pause(Request $request): Response
    {
        $body = $request->jsonBody();
        $playerId = (int) ($body['player_id'] ?? 0);
        $groupId = (int) ($body['group_id'] ?? 0);
        $month = trim((string) ($body['month'] ?? ''));

        if ($playerId === 0 || $groupId === 0 || !preg_match('/^\d{4}-\d{2}$/', $month)) {
            return $this->json(['success' => false, 'error' => 'بيانات ناقصة']);
        }

        $db = App::getInstance()->db();
        $gp = $db->selectOne(
            "SELECT id, paused_months FROM sa_group_players WHERE player_id = ? AND group_id = ? AND status = ?",
            [$playerId, $groupId, SaConstants::STATUS_ACTIVE]
        );

        if (!$gp) {
            return $this->json(['success' => false, 'error' => 'اللاعب غير مسجل في هذه المجموعة']);
        }

        $paused = json_decode($gp['paused_months'] ?? '[]', true) ?: [];
        if (!in_array($month, $paused, true)) {
            $paused[] = $month;
            $db->update('sa_group_players', [
                'paused_months' => json_encode($paused),
                'updated_at'    => date('Y-m-d H:i:s'),
            ], 'id = ?', [(int) $gp['id']]);
        }

        return $this->json(['success' => true, 'paused_months' => $paused]);
    }

    public function unpause(Request $request): Response
    {
        $body = $request->jsonBody();
        $playerId = (int) ($body['player_id'] ?? 0);
        $groupId = (int) ($body['group_id'] ?? 0);
        $month = trim((string) ($body['month'] ?? ''));

        if ($playerId === 0 || $groupId === 0 || !preg_match('/^\d{4}-\d{2}$/', $month)) {
            return $this->json(['success' => false, 'error' => 'بيانات ناقصة']);
        }

        $db = App::getInstance()->db();
        $gp = $db->selectOne(
            "SELECT id, paused_months FROM sa_group_players WHERE player_id = ? AND group_id = ? AND status = ?",
            [$playerId, $groupId, SaConstants::STATUS_ACTIVE]
        );

        if (!$gp) {
            return $this->json(['success' => false, 'error' => 'اللاعب غير مسجل في هذه المجموعة']);
        }

        $paused = json_decode($gp['paused_months'] ?? '[]', true) ?: [];
        $paused = array_values(array_filter($paused, fn($m) => $m !== $month));

        $db->update('sa_group_players', [
            'paused_months' => json_encode($paused),
            'updated_at'    => date('Y-m-d H:i:s'),
        ], 'id = ?', [(int) $gp['id']]);

        return $this->json(['success' => true, 'paused_months' => $paused]);
    }
}
