<?php
declare(strict_types=1);

namespace App\Modules\FacilityDashboards\Services;

use App\Core\App;

final class MirrorDisplayService
{
    public static function getGrid(int $gridId): ?array
    {
        $db = App::getInstance()->db();

        $grid = $db->selectOne(
            "SELECT mg.*, f.name_ar AS facility_name
             FROM mirror_grids mg
             LEFT JOIN facilities f ON f.id = mg.facility_id
             WHERE mg.id = ? AND mg.is_active = 1",
            [$gridId]
        );

        if (!$grid) {
            return null;
        }

        $boxes = $db->select(
            "SELECT mb.*, c.full_name_ar AS coach_full_name, a.name_ar AS academy_name
             FROM mirror_boxes mb
             LEFT JOIN coaches c ON c.id = mb.coach_id
             LEFT JOIN academies a ON a.id = mb.academy_id
             WHERE mb.grid_id = ? AND mb.is_active = 1
             ORDER BY mb.row_index ASC, mb.col_index ASC",
            [$gridId]
        );

        foreach ($boxes as &$box) {
            $box['trainees'] = $db->select(
                "SELECT mbt.*, p.full_name_ar AS player_full_name
                 FROM mirror_box_trainees mbt
                 LEFT JOIN players p ON p.id = mbt.player_id
                 WHERE mbt.box_id = ?
                 ORDER BY mbt.assigned_at ASC",
                [(int) $box['id']]
            );
            $box['trainee_count'] = count($box['trainees']);
        }
        unset($box);

        $grid['boxes'] = $boxes;
        return $grid;
    }

    public static function getAllGrids(): array
    {
        $db = App::getInstance()->db();
        return $db->select(
            "SELECT mg.*, f.name_ar AS facility_name
             FROM mirror_grids mg
             LEFT JOIN facilities f ON f.id = mg.facility_id
             WHERE mg.is_active = 1
             ORDER BY mg.name_ar ASC"
        );
    }

    public static function createGrid(int $facilityId, string $nameAr, int $rows, int $cols): int
    {
        $db = App::getInstance()->db();
        $employee = App::getInstance()->currentEmployee();

        $gridId = $db->insert('mirror_grids', [
            'facility_id' => $facilityId,
            'name_ar'     => $nameAr,
            'rows_count'  => $rows,
            'cols_count'  => $cols,
            'is_active'   => 1,
            'created_by'  => $employee ? ($employee->id ?? $employee['id'] ?? null) : null,
        ]);

        for ($r = 0; $r < $rows; $r++) {
            for ($c = 0; $c < $cols; $c++) {
                $db->insert('mirror_boxes', [
                    'grid_id'      => $gridId,
                    'row_index'    => $r,
                    'col_index'    => $c,
                    'max_trainees' => 5,
                    'is_active'    => 1,
                ]);
            }
        }

        return $gridId;
    }

    public static function updateBox(int $boxId, array $data): void
    {
        $db = App::getInstance()->db();
        $db->update('mirror_boxes', $data, 'id = ?', [$boxId]);
    }

    public static function addTrainee(int $boxId, ?int $playerId, ?string $traineeName): bool
    {
        $db = App::getInstance()->db();

        $box = $db->selectOne("SELECT id, max_trainees FROM mirror_boxes WHERE id = ?", [$boxId]);
        if (!$box) {
            return false;
        }

        $currentCount = $db->selectOne(
            "SELECT COUNT(*) AS cnt FROM mirror_box_trainees WHERE box_id = ?",
            [$boxId]
        )['cnt'] ?? 0;

        if ((int) $currentCount >= (int) $box['max_trainees']) {
            return false;
        }

        $employee = App::getInstance()->currentEmployee();
        $db->insert('mirror_box_trainees', [
            'box_id'       => $boxId,
            'player_id'    => $playerId,
            'trainee_name' => $traineeName,
            'assigned_by'  => $employee ? ($employee->id ?? $employee['id'] ?? null) : null,
        ]);

        return true;
    }

    public static function removeTrainee(int $traineeId): void
    {
        $db = App::getInstance()->db();
        $db->delete('mirror_box_trainees', 'id = ?', [$traineeId]);
    }

    public static function moveTrainee(int $traineeId, int $toBoxId): bool
    {
        $db = App::getInstance()->db();

        $box = $db->selectOne("SELECT id, max_trainees FROM mirror_boxes WHERE id = ?", [$toBoxId]);
        if (!$box) {
            return false;
        }

        $currentCount = $db->selectOne(
            "SELECT COUNT(*) AS cnt FROM mirror_box_trainees WHERE box_id = ?",
            [$toBoxId]
        )['cnt'] ?? 0;

        if ((int) $currentCount >= (int) $box['max_trainees']) {
            return false;
        }

        $db->update('mirror_box_trainees', ['box_id' => $toBoxId], 'id = ?', [$traineeId]);
        return true;
    }

    public static function getGridState(int $gridId): array
    {
        $db = App::getInstance()->db();

        $boxes = $db->select(
            "SELECT mb.id, mb.row_index, mb.col_index, mb.label, mb.coach_name,
                    mb.max_trainees, mb.age_group, mb.gender,
                    c.full_name_ar AS coach_full_name,
                    a.name_ar AS academy_name
             FROM mirror_boxes mb
             LEFT JOIN coaches c ON c.id = mb.coach_id
             LEFT JOIN academies a ON a.id = mb.academy_id
             WHERE mb.grid_id = ? AND mb.is_active = 1
             ORDER BY mb.row_index ASC, mb.col_index ASC",
            [$gridId]
        );

        $result = [];
        foreach ($boxes as $box) {
            $trainees = $db->select(
                "SELECT mbt.id, mbt.trainee_name, p.full_name_ar AS player_name
                 FROM mirror_box_trainees mbt
                 LEFT JOIN players p ON p.id = mbt.player_id
                 WHERE mbt.box_id = ?",
                [(int) $box['id']]
            );

            $result[] = [
                'id'            => (int) $box['id'],
                'row'           => (int) $box['row_index'],
                'col'           => (int) $box['col_index'],
                'label'         => $box['label'],
                'coach'         => $box['coach_full_name'] ?? $box['coach_name'] ?? '',
                'academy'       => $box['academy_name'] ?? '',
                'age_group'     => $box['age_group'] ?? '',
                'gender'        => $box['gender'] ?? 'mixed',
                'max_trainees'  => (int) $box['max_trainees'],
                'trainees'      => array_map(fn($t) => [
                    'id'   => (int) $t['id'],
                    'name' => $t['player_name'] ?? $t['trainee_name'] ?? '',
                ], $trainees),
                'trainee_count' => count($trainees),
            ];
        }

        return $result;
    }
}
