<?php
declare(strict_types=1);

namespace App\Modules\PoolManagement\Controllers;

use App\Core\Controller;
use App\Core\Request;
use App\Core\Response;
use App\Core\App;
use App\Modules\PoolManagement\Models\PoolConfiguration;
use App\Modules\PoolManagement\Services\PoolOccupancyOptimizer;

class PoolDashboardController extends Controller
{
    public function show(Request $request, string $id): Response
    {
        $pool = PoolConfiguration::find((int) $id);
        if (!$pool) {
            return $this->redirect('/pool')->withError('حمام السباحة غير موجود');
        }

        $db = App::getInstance()->db();
        $today = date('Y-m-d');
        $weekStart = date('Y-m-d', strtotime('monday this week'));
        $weekEnd = date('Y-m-d', strtotime('sunday this week'));
        $monthStart = date('Y-m-01');
        $monthEnd = date('Y-m-t');

        // Today stats
        $todayStats = $db->selectOne(
            "SELECT COUNT(*) AS bookings, COALESCE(SUM(expected_swimmers), 0) AS swimmers, COALESCE(SUM(total_amount), 0) AS revenue
             FROM pool_bookings WHERE pool_config_id = ? AND booking_date = ? AND status NOT IN ('cancelled')",
            [(int) $id, $today]
        );

        // Week stats
        $weekStats = $db->selectOne(
            "SELECT COUNT(*) AS bookings, COALESCE(SUM(expected_swimmers), 0) AS swimmers, COALESCE(SUM(total_amount), 0) AS revenue
             FROM pool_bookings WHERE pool_config_id = ? AND booking_date BETWEEN ? AND ? AND status NOT IN ('cancelled')",
            [(int) $id, $weekStart, $weekEnd]
        );

        // Month stats
        $monthStats = $db->selectOne(
            "SELECT COUNT(*) AS bookings, COALESCE(SUM(expected_swimmers), 0) AS swimmers, COALESCE(SUM(total_amount), 0) AS revenue
             FROM pool_bookings WHERE pool_config_id = ? AND booking_date BETWEEN ? AND ? AND status NOT IN ('cancelled')",
            [(int) $id, $monthStart, $monthEnd]
        );

        // Heatmap data: bookings per hour per day of week (last 30 days)
        $heatmapRaw = $db->select(
            "SELECT DAYOFWEEK(booking_date) AS dow, HOUR(start_time) AS hr, COUNT(*) AS cnt
             FROM pool_bookings
             WHERE pool_config_id = ? AND booking_date >= DATE_SUB(CURDATE(), INTERVAL 30 DAY) AND status NOT IN ('cancelled')
             GROUP BY dow, hr",
            [(int) $id]
        );
        $heatmap = [];
        foreach ($heatmapRaw as $row) {
            $heatmap[(int) $row['dow']][(int) $row['hr']] = (int) $row['cnt'];
        }

        // Booking type breakdown (this month)
        $typeBreakdown = $db->select(
            "SELECT booking_type, COUNT(*) AS cnt, COALESCE(SUM(expected_swimmers), 0) AS swimmers
             FROM pool_bookings
             WHERE pool_config_id = ? AND booking_date BETWEEN ? AND ? AND status NOT IN ('cancelled')
             GROUP BY booking_type ORDER BY cnt DESC",
            [(int) $id, $monthStart, $monthEnd]
        );

        // Lane utilization (this month)
        $laneUtilRaw = $db->select(
            "SELECT lanes_json, TIMESTAMPDIFF(MINUTE, start_time, end_time) AS dur_min
             FROM pool_bookings
             WHERE pool_config_id = ? AND booking_date BETWEEN ? AND ? AND status NOT IN ('cancelled')",
            [(int) $id, $monthStart, $monthEnd]
        );
        $lanes = $pool->getLanes();
        $laneMinutes = [];
        foreach ($lanes as $l) $laneMinutes[(int) $l['lane_number']] = 0;
        foreach ($laneUtilRaw as $row) {
            $bookedLanes = json_decode($row['lanes_json'] ?? '[]', true);
            if (is_array($bookedLanes)) {
                foreach ($bookedLanes as $ln) {
                    if (isset($laneMinutes[$ln])) {
                        $laneMinutes[$ln] += (int) $row['dur_min'];
                    }
                }
            }
        }

        $hours = $pool->getOperatingHours();
        $dailyMinutes = (strtotime($hours['end'] ?? '22:00') - strtotime($hours['start'] ?? '06:00')) / 60;
        $daysInMonth = (int) date('t');
        $totalAvailableMinutes = $dailyMinutes * $daysInMonth;

        // Peak hours (top 5 busiest hours this month)
        $peakHours = $db->select(
            "SELECT HOUR(start_time) AS hr, COUNT(*) AS cnt
             FROM pool_bookings
             WHERE pool_config_id = ? AND booking_date BETWEEN ? AND ? AND status NOT IN ('cancelled')
             GROUP BY hr ORDER BY cnt DESC LIMIT 5",
            [(int) $id, $monthStart, $monthEnd]
        );

        return $this->view('PoolManagement.Views.dashboard', [
            'pool'           => $pool,
            'lanes'          => $lanes,
            'todayStats'     => $todayStats,
            'weekStats'      => $weekStats,
            'monthStats'     => $monthStats,
            'heatmap'        => $heatmap,
            'typeBreakdown'  => $typeBreakdown,
            'laneMinutes'    => $laneMinutes,
            'totalAvailableMinutes' => $totalAvailableMinutes,
            'peakHours'      => $peakHours,
            'bookingTypes'   => PoolConfiguration::getBookingTypes(),
        ]);
    }
}
