<?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\Services\PoolGridService;

class PoolGridApiController extends Controller
{
    public function state(Request $request, string $id): Response
    {
        $date = $request->get('date', date('Y-m-d'));
        $startTime = $request->get('start_time', '');
        $endTime = $request->get('end_time', '');

        if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $date)) {
            return $this->json(['error' => 'تاريخ غير صالح'], 400);
        }
        if (!preg_match('/^\d{2}:\d{2}$/', $startTime) || !preg_match('/^\d{2}:\d{2}$/', $endTime)) {
            return $this->json(['error' => 'وقت غير صالح'], 400);
        }

        $state = PoolGridService::getGridState((int) $id, $date, $startTime, $endTime);

        if (isset($state['error'])) {
            return $this->json(['error' => $state['error']], 422);
        }

        return $this->json($state);
    }

    public function assign(Request $request, string $id): Response
    {
        $body = $request->jsonBody();
        $date = trim((string) ($body['date'] ?? ''));
        $action = trim((string) ($body['action'] ?? ''));
        $cells = $body['cells'] ?? [];
        $groupId = !empty($body['group_id']) ? (int) $body['group_id'] : null;
        $notes = trim((string) ($body['notes'] ?? ''));

        // Support multi-slot (slots array) or legacy single start_time/end_time
        if (!empty($body['slots']) && is_array($body['slots'])) {
            $slots = $body['slots'];
        } else {
            $startTime = trim((string) ($body['start_time'] ?? ''));
            $endTime = trim((string) ($body['end_time'] ?? ''));
            $slots = [['start_time' => $startTime, 'end_time' => $endTime]];
        }

        if (!$date || !$action || empty($cells) || empty($slots)) {
            return $this->json(['error' => 'بيانات ناقصة'], 400);
        }

        $result = PoolGridService::bulkAssign((int) $id, $date, $slots, $action, $cells, $groupId, $notes ?: null);

        return $this->json($result, $result['success'] ? 200 : 422);
    }

    public function clear(Request $request, string $id): Response
    {
        $body = $request->jsonBody();
        $date = trim((string) ($body['date'] ?? ''));
        $cells = $body['cells'] ?? [];

        // Support multi-slot or legacy single start_time
        if (!empty($body['slots']) && is_array($body['slots'])) {
            $slots = $body['slots'];
        } else {
            $startTime = trim((string) ($body['start_time'] ?? ''));
            $slots = [['start_time' => $startTime]];
        }

        if (!$date || empty($cells) || empty($slots)) {
            return $this->json(['error' => 'بيانات ناقصة'], 400);
        }

        $result = PoolGridService::bulkClear((int) $id, $date, $slots, $cells);

        return $this->json($result);
    }

    public function updateGrid(Request $request, string $id): Response
    {
        $body = $request->jsonBody();
        $rows = (int) ($body['rows'] ?? 0);
        $cols = (int) ($body['cols'] ?? 0);

        if ($rows < 1 || $cols < 1) {
            return $this->json(['error' => 'عدد الصفوف والأعمدة مطلوب'], 400);
        }

        $result = PoolGridService::updateGridSize((int) $id, $rows, $cols);

        return $this->json($result, $result['success'] ? 200 : 422);
    }

    public function preview(Request $request, string $id): Response
    {
        $date = $request->get('date', date('Y-m-d'));
        $slotsJson = $request->get('slots', '');
        $cellsJson = $request->get('cells', '');
        $action = $request->get('action', 'training');

        $slots = json_decode($slotsJson, true) ?: [];
        $cells = json_decode($cellsJson, true) ?: [];

        if (empty($slots) || empty($cells)) {
            return $this->json(['success' => false, 'error' => 'بيانات ناقصة']);
        }

        $db = App::getInstance()->db();
        $conflicts = 0;
        $free = 0;
        $details = [];

        foreach ($slots as $slot) {
            $startTime = $slot['start_time'] ?? '';
            $endTime = $slot['end_time'] ?? '';
            foreach ($cells as $cell) {
                $row = (int) ($cell['row'] ?? $cell[0] ?? 0);
                $col = (int) ($cell['col'] ?? $cell[1] ?? 0);

                $existing = $db->selectOne(
                    "SELECT id FROM sa_pool_zone_bookings WHERE facility_id = ? AND booking_date = ? AND start_time = ? AND zone_row = ? AND zone_col = ? AND status = 'active'",
                    [(int) $id, $date, $startTime, $row, $col]
                );

                if ($existing) {
                    $conflicts++;
                    $details[] = ['row' => $row, 'col' => $col, 'slot' => $startTime, 'status' => 'conflict'];
                } else {
                    $free++;
                    $details[] = ['row' => $row, 'col' => $col, 'slot' => $startTime, 'status' => 'free'];
                }
            }
        }

        return $this->json([
            'success'   => true,
            'total'     => $conflicts + $free,
            'free'      => $free,
            'conflicts' => $conflicts,
            'details'   => $details,
        ]);
    }

    public function quickRepeat(Request $request, string $id): Response
    {
        $body = $request->jsonBody();
        $date = trim((string) ($body['date'] ?? ''));
        $endDate = trim((string) ($body['end_date'] ?? ''));
        $action = trim((string) ($body['action'] ?? ''));
        $cells = $body['cells'] ?? [];
        $slots = $body['slots'] ?? [];
        $groupId = !empty($body['group_id']) ? (int) $body['group_id'] : null;

        if (!$date || !$endDate || !$action || empty($cells) || empty($slots)) {
            return $this->json(['success' => false, 'error' => 'بيانات ناقصة']);
        }

        $startTs = strtotime($date);
        $endTs = strtotime($endDate);
        $maxDays = 60;
        if ($endTs <= $startTs) {
            return $this->json(['success' => false, 'error' => 'تاريخ النهاية يجب أن يكون بعد تاريخ البداية']);
        }
        if (($endTs - $startTs) / 86400 > $maxDays) {
            $endTs = $startTs + ($maxDays * 86400);
        }

        $dayOfWeek = (int) date('w', $startTs);
        $totalAssigned = 0;
        $totalSkipped = 0;
        $weeks = 0;

        $current = $startTs;
        while ($current <= $endTs) {
            if ((int) date('w', $current) === $dayOfWeek) {
                $dateStr = date('Y-m-d', $current);
                $result = PoolGridService::bulkAssign((int) $id, $dateStr, $slots, $action, $cells, $groupId, null);
                if ($result['success']) {
                    $totalAssigned += (int) ($result['assigned'] ?? 0);
                    $totalSkipped += (int) ($result['skipped'] ?? 0);
                }
                $weeks++;
            }
            $current += 86400;
        }

        return $this->json([
            'success'  => true,
            'assigned' => $totalAssigned,
            'skipped'  => $totalSkipped,
            'weeks'    => $weeks,
        ]);
    }

    public function copySlot(Request $request, string $id): Response
    {
        $body = $request->jsonBody();
        $date = trim((string) ($body['date'] ?? ''));
        $fromTime = trim((string) ($body['from_time'] ?? ''));

        // Support multi-target (to_slots array) or legacy single to_time/to_end_time
        if (!empty($body['to_slots']) && is_array($body['to_slots'])) {
            $toSlots = $body['to_slots'];
        } else {
            $toTime = trim((string) ($body['to_time'] ?? ''));
            $toEndTime = trim((string) ($body['to_end_time'] ?? ''));
            $toSlots = [['start' => $toTime, 'end' => $toEndTime]];
        }

        if (!$date || !$fromTime || empty($toSlots)) {
            return $this->json(['error' => 'بيانات ناقصة'], 400);
        }

        $result = PoolGridService::copySlot((int) $id, $date, $fromTime, $toSlots);

        return $this->json($result, $result['success'] ? 200 : 422);
    }
}
