<?php

// app/Http/Controllers/VipGameController.php

namespace App\Http\Controllers;

use App\Models\Game;
use App\Models\VvipGame;
use App\Models\VvipGameGroup;
use Carbon\Carbon;
use Illuminate\Http\Request;
use App\Models\VipGame;
use App\Models\VipGameGroup;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;

class VvipGameController extends Controller
{
    // Cache duration in minutes - optimized for Redis
    private const CACHE_TTL = 60; // 1 hour
    private const CACHE_TTL_SHORT = 30; // 30 minutes for date-specific queries

    public function index()
    {
        // Cache the query with eager loading
        $VvipGameGroups = Cache::remember('vvip_groups.index', self::CACHE_TTL, function () {
            return VvipGameGroup::with(['games' => function($query) {
                $query->select('id', 'vvip_game_group_id', 'date_time', 'home_team', 'away_team', 'league', 'option', 'odds', 'status');
            }])
                ->select('id', 'price', 'selling', 'status', 'sporty_booking', 'onex_booking', 'msport_booking', 'betway_booking', 'created_at', 'updated_at')
                ->orderBy('created_at', 'desc')
                ->limit(50) // Add reasonable limit
                ->get();
        });

        return response()->json($VvipGameGroups, 200);
    }

    public function store(Request $request)
    {
        $validated = $request->validate([
            'price' => 'required|numeric',
            'selling' => 'required|boolean',
            'sporty_booking' => 'nullable|string',
            'onex_booking' => 'nullable|string',
            'msport_booking' => 'nullable|string',
            'betway_booking' => 'nullable|string',
            'created_at' => 'nullable|date',
            'games' => 'required|array',
            'games.*.date_time' => 'required|date',
            'games.*.home_team' => 'required|string|max:255',
            'games.*.away_team' => 'required|string|max:255',
            'games.*.league' => 'required|string|max:255',
            'games.*.option' => 'required|string|max:255',
            'games.*.odds' => 'required|numeric',
        ]);

        DB::beginTransaction();
        try {
            $vvipGameGroup = VvipGameGroup::create([
                'price' => $validated['price'],
                'selling' => $validated['selling'],
                'sporty_booking' => $validated['sporty_booking'] ?? null,
                'onex_booking' => $validated['onex_booking'] ?? null,
                'msport_booking' => $validated['msport_booking'] ?? null,
                'betway_booking' => $validated['betway_booking'] ?? null,
                'created_at' => $validated['created_at'] ?? Carbon::now(),
            ]);

            // Bulk insert games for better performance
            $games = $validated['games'];
            $timestamp = now();
            $bulkGames = array_map(function($game) use ($vvipGameGroup, $timestamp) {
                $game['vvip_game_group_id'] = $vvipGameGroup->id;
                $game['created_at'] = $timestamp;
                $game['updated_at'] = $timestamp;
                return $game;
            }, $games);

            VvipGame::insert($bulkGames);

            // Fetch the created games for response
            $createdGames = VvipGame::where('vvip_game_group_id', $vvipGameGroup->id)->get();

            DB::commit();

            // Clear relevant caches
            $this->clearVvipCaches();

            return response()->json(['group' => $vvipGameGroup, 'games' => $createdGames], 201);

        } catch (\Exception $e) {
            DB::rollBack();
            Log::error('Error creating VIP game group: ' . $e->getMessage());
            return response()->json(['message' => 'Error creating VIP games'], 500);
        }
    }

    public function show($id)
    {
        // Cache individual group lookups
        $cacheKey = "vvip_group.{$id}";
        $vvipGameGroup = Cache::remember($cacheKey, self::CACHE_TTL, function () use ($id) {
            return VvipGameGroup::with(['games' => function($query) {
                $query->select('id', 'vvip_game_group_id', 'date_time', 'home_team', 'away_team', 'league', 'option', 'odds', 'status');
            }])->find($id);
        });

        if (is_null($vvipGameGroup)) {
            return response()->json(['message' => 'Group Not Found'], 404);
        }

        return response()->json($vvipGameGroup, 200);
    }

    public function update(Request $request, $id)
    {
        $vvipGameGroup = VvipGameGroup::find($id);
        if (is_null($vvipGameGroup)) {
            return response()->json(['message' => 'Group Not Found'], 404);
        }

        DB::beginTransaction();
        try {
            // Update group fields
            $vvipGameGroup->update($request->only('price', 'selling', 'msport_booking', 'onex_booking', 'betway_booking', 'sporty_booking', 'created_at'));

            // Handle nested games array
            if ($request->has('games')) {
                $games = $request->input('games');

                // Delete existing games in one query
                VvipGame::where('vvip_game_group_id', $id)->delete();

                // Bulk insert new games
                $timestamp = now();
                $bulkGames = array_map(function($game) use ($id, $timestamp) {
                    $game['vvip_game_group_id'] = $id;
                    $game['created_at'] = $timestamp;
                    $game['updated_at'] = $timestamp;
                    return $game;
                }, $games);

                VvipGame::insert($bulkGames);
            }

            // Load the updated games relationship
            $vvipGameGroup->load('games');

            DB::commit();

            // Clear caches
            Cache::forget("vvip_group.{$id}");
            $this->clearVvipCaches();

            return response()->json($vvipGameGroup, 200);

        } catch (\Exception $e) {
            DB::rollBack();
            Log::error('Error updating VIP game group: ' . $e->getMessage());
            return response()->json(['message' => 'Error updating VIP games'], 500);
        }
    }

    public function destroy($id)
    {
        $vvipGameGroup = VvipGameGroup::find($id);
        if (is_null($vvipGameGroup)) {
            return response()->json(['message' => 'Group Not Found'], 404);
        }

        DB::beginTransaction();
        try {
            $vvipGameGroup->delete(); // This will cascade delete games if foreign key is set
            DB::commit();

            // Clear caches
            Cache::forget("vvip_group.{$id}");
            $this->clearVvipCaches();

            return response()->json(['message' => 'Group Deleted'], 204);

        } catch (\Exception $e) {
            DB::rollBack();
            Log::error('Error deleting VIP game group: ' . $e->getMessage());
            return response()->json(['message' => 'Error deleting group'], 500);
        }
    }

    public function updateStatus(Request $request, $id)
    {
        $request->validate([
            'status' => 'nullable|in:Won,Lost',
            'type' => 'required|in:group,individual',
        ]);

        DB::beginTransaction();
        try {
            if ($request->type === 'group') {
                $gameGroup = VvipGameGroup::findOrFail($id);
                $gameGroup->status = $request->status;
                $gameGroup->save();

                // If group status is Won, also set all individual games to Won
                if ($request->status === 'Won') {
                    VvipGame::where('vvip_game_group_id', $id)->update(['status' => 'Won']);
                }

                // If group status is reset to null/default, also reset all individual games
                if ($request->status === null) {
                    VvipGame::where('vvip_game_group_id', $id)->update(['status' => null]);
                }

                // Clear cache for this group
                Cache::forget("vvip_group.{$id}");
                $this->clearVvipCaches();

                DB::commit();
                return response()->json(['message' => 'Group game status updated successfully']);

            } else if ($request->type === 'individual') {
                $individualGame = VvipGame::findOrFail($id);
                $individualGame->status = $request->status;
                $individualGame->save();

                // Clear cache for the parent group
                if ($individualGame->vvip_game_group_id) {
                    Cache::forget("vvip_group.{$individualGame->vvip_game_group_id}");
                }
                $this->clearVvipCaches();

                DB::commit();
                return response()->json(['message' => 'Individual game status updated successfully']);
            }

            return response()->json(['message' => 'Invalid request'], 400);

        } catch (\Exception $e) {
            DB::rollBack();
            Log::error('Error updating VIP game status: ' . $e->getMessage());
            return response()->json(['message' => 'Error updating status'], 500);
        }
    }

    public function getVvIPGamesByDateRange(Request $request)
    {
        $date = $request->query('date');
        if (!$date) {
            return response()->json(['message' => 'Date is required'], 400);
        }

        $parsedDate = Carbon::parse($date)->format('Y-m-d');

        // Cache with date-specific key
        $cacheKey = "vvip_groups_by_date.{$parsedDate}";
        $vvipGameGroups = Cache::remember($cacheKey, self::CACHE_TTL_SHORT, function () use ($date) {
            return VvipGameGroup::with(['games' => function($query) {
                $query->select('id', 'vvip_game_group_id', 'date_time', 'home_team', 'away_team', 'league', 'option', 'odds', 'status');
            }])
                ->select('id', 'price', 'selling', 'status', 'sporty_booking', 'onex_booking', 'msport_booking', 'betway_booking', 'created_at', 'updated_at')
                ->whereDate('created_at', $date)
                ->orderBy('created_at', 'desc')
                ->get();
        });

        return response()->json($vvipGameGroups, 200);
    }

    /**
     * Clear all VVIP-related caches
     */
    private function clearVvipCaches()
    {
        Cache::forget('vvip_groups.index');

        // Clear date-specific caches for the last 7 days
        for ($i = 0; $i < 7; $i++) {
            $date = Carbon::now()->subDays($i)->format('Y-m-d');
            Cache::forget("vvip_groups_by_date.{$date}");
        }

        // If using cache tags (Redis) - only use if Redis supports it
        if (Cache::getStore() instanceof \Illuminate\Cache\RedisStore) {
            try {
                Cache::tags(['vvip_groups'])->flush();
            } catch (\Exception $e) {
                // Tags might not be supported, continue without error
            }
        }
    }
}
