<?php
declare(strict_types=1);

namespace App\Modules\ParentApi\Controllers\Api;

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

final class ChildrenController extends ApiController
{
    public function index(Request $request): Response
    {
        $parent = App::getInstance()->currentParent();
        $db = App::getInstance()->db();

        $links = $db->select(
            "SELECT ppl.*, p.full_name_ar, p.full_name_en, p.date_of_birth, p.gender,
                    p.photo_path, p.medical_status, p.card_status, p.phone
             FROM parent_player_links ppl
             JOIN players p ON p.id = ppl.player_id AND p.is_archived = 0
             WHERE ppl.parent_id = ?
             ORDER BY p.full_name_ar ASC",
            [(int) $parent->id]
        );

        $children = array_map(fn(array $link) => [
            'player_id' => (int) $link['player_id'],
            'full_name_ar' => $link['full_name_ar'],
            'full_name_en' => $link['full_name_en'],
            'date_of_birth' => $link['date_of_birth'],
            'gender' => $link['gender'],
            'photo_path' => $link['photo_path'],
            'medical_status' => $link['medical_status'],
            'card_status' => $link['card_status'],
            'relationship' => $link['relationship'],
            'is_primary_contact' => (bool) $link['is_primary_contact'],
            'permissions' => [
                'evaluations' => (bool) $link['can_view_evaluations'],
                'attendance' => (bool) $link['can_view_attendance'],
                'medical' => (bool) $link['can_view_medical'],
                'financials' => (bool) $link['can_view_financials'],
                'approve_group_change' => (bool) $link['can_approve_group_change'],
            ],
        ], $links);

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

    public function dashboard(Request $request, int $playerId): Response
    {
        $parent = App::getInstance()->currentParent();
        $db = App::getInstance()->db();

        $link = $this->verifyAccess($db, (int) $parent->id, $playerId);
        if (!$link) {
            return $this->errorResponse('غير مصرح بالوصول لهذا اللاعب', 403, [], ApiErrorCodes::FORBIDDEN);
        }

        $player = $db->selectOne("SELECT * FROM players WHERE id = ? AND is_archived = 0", [$playerId]);
        if (!$player) {
            return $this->errorResponse('اللاعب غير موجود', 404, [], ApiErrorCodes::NOT_FOUND);
        }

        $dashboard = [
            'player' => [
                'id' => (int) $player['id'],
                'full_name_ar' => $player['full_name_ar'],
                'date_of_birth' => $player['date_of_birth'],
                'gender' => $player['gender'],
                'photo_path' => $player['photo_path'],
                'medical_status' => $player['medical_status'],
                'medical_expiry_date' => $player['medical_expiry_date'],
                'card_status' => $player['card_status'],
            ],
            'groups' => $this->getActiveGroups($db, $playerId),
        ];

        if ($link['can_view_attendance']) {
            $dashboard['recent_attendance'] = $this->getRecentAttendance($db, $playerId);
        }
        if ($link['can_view_evaluations']) {
            $dashboard['recent_evaluations'] = $this->getRecentEvaluations($db, $playerId);
        }
        if ($link['can_view_financials']) {
            $dashboard['financial_summary'] = $this->getFinancialSummary($db, $player);
        }

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

    public function attendance(Request $request, int $playerId): Response
    {
        $parent = App::getInstance()->currentParent();
        $db = App::getInstance()->db();

        $link = $this->verifyAccess($db, (int) $parent->id, $playerId);
        if (!$link || !$link['can_view_attendance']) {
            return $this->errorResponse('غير مصرح بعرض الحضور', 403, [], ApiErrorCodes::FORBIDDEN);
        }

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

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

        $records = $db->select(
            "SELECT sa.status, sa.check_in_time, sa.check_out_time, sa.is_makeup, sa.notes,
                    ts.session_date, ts.start_time, ts.end_time, ts.session_type,
                    tg.name_ar as group_name
             FROM session_attendance sa
             JOIN training_sessions ts ON ts.id = sa.session_id
             JOIN training_groups tg ON tg.id = ts.group_id
             WHERE sa.player_id = ?
             ORDER BY ts.session_date DESC, ts.start_time DESC
             LIMIT ? OFFSET ?",
            [$playerId, $perPage, $offset]
        );

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

    public function evaluations(Request $request, int $playerId): Response
    {
        $parent = App::getInstance()->currentParent();
        $db = App::getInstance()->db();

        $link = $this->verifyAccess($db, (int) $parent->id, $playerId);
        if (!$link || !$link['can_view_evaluations']) {
            return $this->errorResponse('غير مصرح بعرض التقييمات', 403, [], ApiErrorCodes::FORBIDDEN);
        }

        $evaluations = $db->select(
            "SELECT pe.evaluation_date, pe.overall_score, pe.skill_level, pe.scores_json,
                    pe.strengths_ar, pe.weaknesses_ar, pe.coach_notes,
                    c.full_name_ar as coach_name, sd.name_ar as discipline_name
             FROM player_evaluations pe
             LEFT JOIN coaches c ON c.id = pe.evaluator_coach_id
             LEFT JOIN sport_disciplines sd ON sd.id = pe.discipline_id
             WHERE pe.player_id = ? AND pe.parent_visible = 1 AND pe.status = 'approved'
             ORDER BY pe.evaluation_date DESC
             LIMIT 20",
            [$playerId]
        );

        foreach ($evaluations as &$eval) {
            $eval['scores'] = $eval['scores_json'] ? json_decode($eval['scores_json'], true) : [];
            unset($eval['scores_json']);
        }

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

    public function medical(Request $request, int $playerId): Response
    {
        $parent = App::getInstance()->currentParent();
        $db = App::getInstance()->db();

        $link = $this->verifyAccess($db, (int) $parent->id, $playerId);
        if (!$link || !$link['can_view_medical']) {
            return $this->errorResponse('غير مصرح بعرض السجلات الطبية', 403, [], ApiErrorCodes::FORBIDDEN);
        }

        $records = $db->select(
            "SELECT record_type, exam_date, expiry_date, doctor_name, clinic_name,
                    result, restrictions
             FROM player_medical_records
             WHERE player_id = ?
             ORDER BY exam_date DESC LIMIT 10",
            [$playerId]
        );

        $injuries = $db->select(
            "SELECT injury_type, body_part, severity, description_ar, occurred_date,
                    status, estimated_recovery_days
             FROM player_injuries
             WHERE player_id = ? AND status IN ('active', 'recovering')
             ORDER BY occurred_date DESC",
            [$playerId]
        );

        return $this->successResponse([
            'medical_records' => $records,
            'active_injuries' => $injuries,
        ]);
    }

    public function financials(Request $request, int $playerId): Response
    {
        $parent = App::getInstance()->currentParent();
        $db = App::getInstance()->db();

        $link = $this->verifyAccess($db, (int) $parent->id, $playerId);
        if (!$link || !$link['can_view_financials']) {
            return $this->errorResponse('غير مصرح بعرض البيانات المالية', 403, [], ApiErrorCodes::FORBIDDEN);
        }

        $player = $db->selectOne("SELECT id, member_id FROM players WHERE id = ?", [$playerId]);

        $subscriptions = $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 12",
            [$playerId]
        );

        $data = ['subscriptions' => $subscriptions, 'fines' => [], 'installments' => null, 'recent_payments' => []];

        if ($player['member_id']) {
            $memberId = (int) $player['member_id'];

            $data['fines'] = $db->select(
                "SELECT fine_type, amount, paid_amount, penalty_type, status, created_at
                 FROM fines
                 WHERE member_id = ? AND status IN ('imposed', 'appeal_upheld')
                 ORDER BY created_at DESC LIMIT 10",
                [$memberId]
            );

            $plan = $db->selectOne(
                "SELECT * FROM installment_plans WHERE member_id = ? AND status = 'active' LIMIT 1",
                [$memberId]
            );
            if ($plan) {
                $schedule = $db->select(
                    "SELECT installment_number, due_date, amount, paid_amount, status
                     FROM installment_schedule
                     WHERE installment_plan_id = ?
                     ORDER BY installment_number ASC",
                    [(int) $plan['id']]
                );
                $data['installments'] = [
                    'total_amount' => $plan['total_amount'],
                    'monthly_payment' => $plan['monthly_payment'],
                    'remaining_balance' => $plan['remaining_balance'],
                    'status' => $plan['status'],
                    'schedule' => $schedule,
                ];
            }

            $data['recent_payments'] = $db->select(
                "SELECT payment_type, amount, payment_method, payment_date
                 FROM payments
                 WHERE (member_id = ? OR player_id = ?) AND is_voided = 0
                 ORDER BY payment_date DESC LIMIT 20",
                [$memberId, $playerId]
            );
        }

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

    public function achievements(Request $request, int $playerId): Response
    {
        $parent = App::getInstance()->currentParent();
        $db = App::getInstance()->db();

        $link = $this->verifyAccess($db, (int) $parent->id, $playerId);
        if (!$link) {
            return $this->errorResponse('غير مصرح بالوصول لهذا اللاعب', 403, [], ApiErrorCodes::FORBIDDEN);
        }

        $achievements = $db->select(
            "SELECT pa.earned_at, pa.points_earned,
                    ad.name_ar, ad.icon, ad.badge_color, ad.category
             FROM player_achievements pa
             JOIN achievement_definitions ad ON ad.id = pa.achievement_id
             WHERE pa.player_id = ?
             ORDER BY pa.earned_at DESC LIMIT 30",
            [$playerId]
        );

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

    private function verifyAccess(\App\Core\Database $db, int $parentId, int $playerId): ?array
    {
        return $db->selectOne(
            "SELECT * FROM parent_player_links WHERE parent_id = ? AND player_id = ?",
            [$parentId, $playerId]
        );
    }

    private function getActiveGroups(\App\Core\Database $db, int $playerId): array
    {
        return $db->select(
            "SELECT tg.name_ar, tg.day_of_week, tg.start_time, tg.end_time,
                    c.full_name_ar as coach_name
             FROM group_memberships gm
             JOIN training_groups tg ON tg.id = gm.group_id
             LEFT JOIN coaches c ON c.id = tg.coach_id
             WHERE gm.player_id = ? AND gm.status = 'active'",
            [$playerId]
        );
    }

    private function getRecentAttendance(\App\Core\Database $db, int $playerId): array
    {
        return $db->select(
            "SELECT sa.status, ts.session_date, tg.name_ar as group_name
             FROM session_attendance sa
             JOIN training_sessions ts ON ts.id = sa.session_id
             JOIN training_groups tg ON tg.id = ts.group_id
             WHERE sa.player_id = ?
             ORDER BY ts.session_date DESC LIMIT 10",
            [$playerId]
        );
    }

    private function getRecentEvaluations(\App\Core\Database $db, int $playerId): array
    {
        return $db->select(
            "SELECT evaluation_date, overall_score, skill_level
             FROM player_evaluations
             WHERE player_id = ? AND parent_visible = 1 AND status = 'approved'
             ORDER BY evaluation_date DESC LIMIT 5",
            [$playerId]
        );
    }

    private function getFinancialSummary(\App\Core\Database $db, array $player): array
    {
        $outstanding = $db->selectOne(
            "SELECT COALESCE(SUM(total_amount), 0) as total_due
             FROM activity_subscriptions
             WHERE player_id = ? AND status IN ('pending', 'overdue')",
            [(int) $player['id']]
        );

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

        return [
            'subscriptions_due' => $outstanding['total_due'] ?? '0.00',
            'fines_due' => $finesOwed['total'] ?? '0.00',
        ];
    }
}
