<?php

namespace App\Http\Controllers;

use App\Models\BookedSlot;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;

class HomeController extends Controller
{

    public function dashboard(Request $request)
    {
        if (Auth::user()->hasRole('User')) {
            return redirect()->route('home');
        }

        // 1. Date Range Filter
        $startDate = $request->input('start_date') ? Carbon::parse($request->input('start_date')) : Carbon::now()->startOfMonth();
        $endDate = $request->input('end_date') ? Carbon::parse($request->input('end_date')) : Carbon::now()->endOfMonth();

        // Previous Period for Trend Calculation
        $daysDiff = $startDate->diffInDays($endDate) + 1;
        $prevStartDate = $startDate->copy()->subDays($daysDiff);
        $prevEndDate = $endDate->copy()->subDays($daysDiff);

        // 2. Base Queries
        $bookingsQuery = BookedSlot::whereBetween('date', [$startDate->format('Y-m-d'), $endDate->format('Y-m-d')])
            ->where('status', '!=', 'Cancelled');

        $prevBookingsQuery = BookedSlot::whereBetween('date', [$prevStartDate->format('Y-m-d'), $prevEndDate->format('Y-m-d')])
            ->where('status', '!=', 'Cancelled');

        // 3. Key Metrics
        $totalBookings = $bookingsQuery->count();
        $prevTotalBookings = $prevBookingsQuery->count();
        $bookingGrowth = $prevTotalBookings > 0 ? (($totalBookings - $prevTotalBookings) / $prevTotalBookings) * 100 : 100;

        $totalRevenue = $bookingsQuery->sum('amount');
        $prevTotalRevenue = $prevBookingsQuery->sum('amount');
        $revenueGrowth = $prevTotalRevenue > 0 ? (($totalRevenue - $prevTotalRevenue) / $prevTotalRevenue) * 100 : 100;

        $activeVenues = \App\Models\BookingFor::count();
        // Simple utilization approximation: Total Booked Slots / (Active Venues * Days * 12 slots/day approx) * 100
        // Assuming ~12 slots per day per venue
        $totalCapacity = $activeVenues * $daysDiff * 12;
        $utilizationRate = $totalCapacity > 0 ? round(($totalBookings / $totalCapacity) * 100, 1) : 0;


        // 4. Revenue Trend (Daily)
        $revenueTrend = BookedSlot::selectRaw('DATE(date) as date, SUM(amount) as total')
            ->whereBetween('date', [$startDate->format('Y-m-d'), $endDate->format('Y-m-d')])
            ->where('status', '!=', 'Cancelled')
            ->groupBy('date')
            ->orderBy('date')
            ->get()
            ->keyBy('date');

        // Fill missing dates
        $chartLabels = [];
        $chartData = [];
        $current = $startDate->copy();
        while ($current <= $endDate) {
            $dateStr = $current->format('Y-m-d');
            $chartLabels[] = $current->format('d M');
            $chartData[] = isset($revenueTrend[$dateStr]) ? $revenueTrend[$dateStr]->total : 0;
            $current->addDay();
        }

        // 5. Service Split (Turf vs Pool)
        $serviceSplit = DB::table('booked_slots')
            ->join('booking_fors', 'booked_slots.booking_for_id', '=', 'booking_fors.id')
            ->whereBetween('booked_slots.date', [$startDate->format('Y-m-d'), $endDate->format('Y-m-d')])
            ->where('booked_slots.status', '!=', 'Cancelled')
            ->selectRaw("booking_fors.service as service, COUNT(*) as count, SUM(booked_slots.amount) as revenue")
            ->groupBy('booking_fors.service')
            ->get();

        $serviceLabels = $serviceSplit->pluck('service');
        $serviceRevenue = $serviceSplit->pluck('revenue');

        // 6. Booking Status
        $bookingStatus = BookedSlot::whereBetween('date', [$startDate->format('Y-m-d'), $endDate->format('Y-m-d')])
            ->selectRaw('status, COUNT(*) as count')
            ->groupBy('status')
            ->pluck('count', 'status');

        $statusCounts = [
            'Confirmed' => $bookingStatus['Confirmed'] ?? 0,
            'Pending' => $bookingStatus['Pending'] ?? 0,
            'Cancelled' => BookedSlot::whereBetween('date', [$startDate->format('Y-m-d'), $endDate->format('Y-m-d')])->where('status', 'Cancelled')->count() // fetch explicitly
        ];

        // 7. Top Locations
        // Correct Top Locations Logic using DB query since direct relationship to BookedSlot might be missing or complex to filter
        $topLocationsData = DB::table('booked_slots')
            ->join('booking_fors', 'booked_slots.booking_for_id', '=', 'booking_fors.id')
            ->whereBetween('booked_slots.date', [$startDate->format('Y-m-d'), $endDate->format('Y-m-d')])
            ->where('booked_slots.status', '!=', 'Cancelled')
            ->selectRaw('booking_fors.service as name, COUNT(*) as bookings_count, SUM(booked_slots.amount) as revenue')
            ->groupBy('booking_fors.id', 'booking_fors.service')
            ->orderByDesc('bookings_count')
            ->limit(5)
            ->get();

        // 8. Upcoming Bookings
        $upcomingBookings = BookedSlot::with(['user', 'bookingFor'])
            ->where('date', '>=', Carbon::now()->format('Y-m-d'))
            ->where('status', '!=', 'Cancelled')
            ->orderBy('date')
            ->orderBy('time')
            ->limit(6)
            ->get();

        // 9. Peak Time Heatmap (Hour of day)
        $peakHours = BookedSlot::whereBetween('date', [$startDate->format('Y-m-d'), $endDate->format('Y-m-d')])
            ->where('status', '!=', 'Cancelled')
            ->selectRaw('time, COUNT(*) as count')
            ->groupBy('time')
            ->orderBy('time')
            ->get();
        // Need to process this into time slots. Assumes 'time' is stored consistently (e.g. "14:00:00" or "2 PM")

        // 10. Customer Retention (New vs Recurring)
        // A returning customer is one who has > 1 booking total (lifetime), but for this chart we want to see within this period who booked?
        // Usually "Retention" means % of bookings in this period made by returning users.
        // Let's get all user_ids who booked in this period
        $periodUserIds = BookedSlot::whereBetween('date', [$startDate->format('Y-m-d'), $endDate->format('Y-m-d')])
            ->where('status', '!=', 'Cancelled')
            ->pluck('user_id')
            ->unique();

        $returningUsersCount = 0;
        $newUsersCount = 0;

        if ($periodUserIds->count() > 0) {
            // For each user, check if they had a booking BEFORE this period start date
            $returningUsersCount = BookedSlot::whereIn('user_id', $periodUserIds)
                ->where('date', '<', $startDate->format('Y-m-d'))
                ->distinct('user_id')
                ->count();

            $newUsersCount = $periodUserIds->count() - $returningUsersCount;
        }

        // 11. Payment Method Split
        // Assumes 'payment_status' or joins with 'Transaction'. 
        // Checking Transaction model: it has 'status', 'booking_id'. BookedSlot has 'transaction_id'.
        // Simplified: Check BookedSlot 'payment_status'. 'Paid' -> Online likely if transaction_id exists (or Razorpay). 'Unpaid'/'Partial' might be cash/pending.
        // Better: Join Transactions to see method? Transaction has 'razorpay_payment_id', no specific 'method' column shown in fillable.
        // Let's assume for now: If transaction_id is present => Online, else => Cash/Offline/Pending
        $paymentMethods = BookedSlot::whereBetween('date', [$startDate->format('Y-m-d'), $endDate->format('Y-m-d')])
            ->where('status', '!=', 'Cancelled')
            ->selectRaw("CASE WHEN transaction_id IS NOT NULL THEN 'Online' ELSE 'Offline' END as method, COUNT(*) as count")
            ->groupBy('method')
            ->get();

        $paymentMethodLabels = $paymentMethods->pluck('method');
        $paymentMethodCounts = $paymentMethods->pluck('count');

        // 12. Current Venue Status (Real-time)
        // Check if any slot is currently active (now)
        $nowDate = Carbon::now()->format('Y-m-d');
        $nowTime = Carbon::now()->format('H:i:s');

        // Fetch all venues
        $allVenues = \App\Models\BookingFor::all();
        $venueStatus = [];

        foreach ($allVenues as $venue) {
            // Check if there is a booking for this venue right now
            // Assumes slots are 1 hour default. If slots have end_time, use that.
            // Using time as start time.
            $isOccupied = BookedSlot::where('booking_for_id', $venue->id)
                ->where('date', $nowDate)
                ->where('time', '<=', $nowTime)
                ->where(DB::raw("ADDTIME(time, '01:00:00')"), '>', $nowTime) // Assume 1 hour duration
                ->where('status', '!=', 'Cancelled')
                ->exists();

            $venueStatus[] = [
                'name' => $venue->service, // or venue name if different
                'status' => $isOccupied ? 'Occupied' : 'Available',
                'icon' => $venue->service == 'Pool' ? 'fa-tint' : 'fa-futbol-o'
            ];
        }


        return view('admin.dashboard.index', compact(
            'totalBookings',
            'bookingGrowth',
            'totalRevenue',
            'revenueGrowth',
            'activeVenues',
            'utilizationRate',
            'chartLabels',
            'chartData',
            'serviceLabels',
            'serviceRevenue',
            'statusCounts',
            'topLocationsData',
            'upcomingBookings',
            'peakHours',
            'returningUsersCount',
            'newUsersCount',
            'startDate',
            'endDate',
            'paymentMethodLabels',
            'paymentMethodCounts',
            'venueStatus'
        ));
    }

    public function index()
    {
        return view('user.home');
    }


    public function myBooking()
    {
        $user = Auth::user();

        // Fetch all bookings for the user
        $allSlots = BookedSlot::where('user_id', $user->id)
            ->with(['bookingFor', 'transaction'])
            ->orderBy('date', 'desc')
            ->orderBy('time', 'asc')
            ->get();

        // Group by group_id (or individual slot if no group_id)
        $groupedBookings = $allSlots->groupBy(function ($slot) {
            return $slot->group_id ?? 'single_' . $slot->id;
        });

        // Transform into booking groups for the view
        $bookings = $groupedBookings->map(function ($slots, $groupId) {
            $firstSlot = $slots->first();
            $totalAmount = $slots->sum('amount');
            $timeSlots = $slots->pluck('time')->map(function ($time) {
                return Carbon::parse($time)->format('g:i A');
            })->toArray();

            return (object) [
                'group_id' => $groupId,
                'booking_for_id' => $firstSlot->booking_for_id,
                'bookingFor' => $firstSlot->bookingFor,
                'user_id' => $firstSlot->user_id,
                'date' => $firstSlot->date,
                'time_slots' => $timeSlots,
                'time_slots_raw' => $slots->pluck('time')->toArray(),
                'total_amount' => $totalAmount,
                'status' => $firstSlot->status,
                'payment_status' => $firstSlot->payment_status,
                'transaction_id' => $firstSlot->transaction_id,
                'transaction' => $firstSlot->transaction,
                'created_at' => $firstSlot->created_at,
                'slot_count' => $slots->count(),
                'slots' => $slots // Keep individual slots for reference
            ];
        })->sortByDesc('created_at')->values();

        return view('user.my_booking')->with('bookings', $bookings);
    }
}
