<?php

namespace App\Http\Controllers;

use App\Models\Club;
use App\Models\Court;
use App\Models\CourtMedia;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
use Yajra\DataTables\Facades\DataTables;

class CourtController extends Controller
{
    protected $module, $data = [];

    public function __construct()
    {
        $this->module = new Court();
        $this->data['module_name'] = 'Court';
        $this->data['view_directory'] = 'pages.court';
        $this->data['parent_named_route'] = 'courts';
    }

    public function index(Request $request, $club_id)
    {
        if ($request->ajax()) {

            $data = $this->module::with('club')->where('club_id', $club_id);

            // $sno = 1;
            return DataTables::of($data)
                ->addIndexColumn()
                ->addColumn('sno', function ($row) {
                    static $index = 0; // Static variable to keep track of the index
                    $page = request()->get('start', 0); // Get the start parameter
                    $index++;
                    return $page + $index;
                })
                ->addColumn('action', function ($row) {

                    $edit = '<a href="' . route("courts.edit", ['id' => $row->id]) . '" class="edit btn btn-primary btn-sm btn-equal mb-1">Edit</a>&nbsp;';

                    if ($row->status) {
                        $status = '<a href="' . route("courts.status", ['id' => $row->id]) . '" class="edit btn btn-danger btn-sm btn-equal mb-1">Deactivate</a>';
                    } else {
                        $status = '<a href="' . route("courts.status", ['id' => $row->id]) . '" class="edit btn btn-success btn-sm btn-equal mb-1">Activate</a>';
                    }

                    // $delete = '<a href="' . route("courts.delete", ['id' => $row->id]) . '" class="edit btn btn-danger btn-sm btn-equal mb-1">Delete</a>';
                    $delete = '<a href="#" onclick="confirmDelete(\'' . $this->data['parent_named_route'] . '\', ' . $row->id . ')" class="edit btn btn-danger btn-sm btn-equal mb-1">Delete</a>';

                    return $edit . $status . $delete;
                })
                ->addColumn('club_name', function ($row) {

                    $club_name =  $row->club->name;

                    return $club_name;
                })
                ->addColumn('status', function ($row) {
                    return $row->status
                        ? '<i style="color:green;" class="menu-icon tf-icons bx bx-user-check"></i> Active'
                        : '<i style="color:red;" class="menu-icon tf-icons bx bx-user-x"></i> Inactive';
                })
                ->rawColumns(['action', 'status', 'club_name'])
                ->make(true);
        }

        $this->data['page'] =  'List';
        $this->data['club_id'] =  $club_id;

        return view($this->data['view_directory'] . '.' . __FUNCTION__, $this->data);
    }

    public function view(Request $request)
    {
        $this->data['court'] = $this->module::with('club')->find($request->id);

        $this->data['page'] = __FUNCTION__;

        return view($this->data['view_directory'] . '.' . __FUNCTION__, $this->data);
    }

    public function create(Request $request)
    {
        if ($request->isMethod('post')) {
            $validatedData = $request->validate([
                'club_id'       => 'required|string',
                'name'       => 'required|string',
            ]);

            $club_id = $request->club_id;

            $club = Club::find($club_id);

            $court_count = $this->module::where('club_id', $club_id)->count();

            if ($court_count >= $club->total_courts) {
                return redirect()->route('courts.index', ['club_id' => $club_id])->with('error', 'The allowed courts in ' . $club->name . ' are ' . $club->total_courts);
            }

            $court = $this->module->create($validatedData);

            return redirect()->route('courts.index', ['club_id' => $request->club_id])->with('success', $this->data['module_name'] . ' added successfully');
        }

        // Remove the hasRole check and always load all clubs for super admin or user's clubs for others
        // if (auth()->user()->roles()->where('name', 'super admin')->exists()) {
        //     $this->data['clubs'] = Club::all();
        // } else {
        //     $this->data['clubs'] = Club::where('user_id', auth()->user()->id)->get();
        // }
        $this->data['clubs'] = Club::all();

        return view($this->data['view_directory'] . '.' . __FUNCTION__, $this->data);
    }

    /**
     * Create a new court with advanced geolocation and media upload capabilities
     */
    public function createCourt(Request $request)
    {
        if ($request->isMethod('post')) {
            // Comprehensive validation
            $validator = Validator::make($request->all(), [
                'name' => 'required|string|max:255',
                'location' => 'required|string|max:500',
                'latitude' => 'required|numeric|between:-90,90',
                'longitude' => 'required|numeric|between:-180,180',
                'city' => 'required|string|max:100',
                'state' => 'required|string|max:100',
                'zip' => 'required|string|max:20',
                'description' => 'nullable|string|max:1000',
                'phone' => 'nullable|string|max:20',
                'email' => 'nullable|email|max:255',
                'website' => 'nullable|url|max:255',
                // 'amenities' => 'nullable|array',
                // 'amenities.*' => 'string|max:100',
                // 'surfaces' => 'nullable|string|max:255',
                // 'nets' => 'nullable|array',
                // 'nets.*' => 'string|max:100',
                'no_indoor_courts' => 'nullable|integer|min:0|max:100',
                'no_outdoor_courts' => 'nullable|integer|min:0|max:100',
                'images' => 'nullable|array|max:10',
                'images.*' => 'image|mimes:jpeg,png,jpg,gif,webp|max:5120', // 5MB max per image
                'cropped_images' => 'nullable|array',
                'cropped_images.*' => 'string', // Base64 encoded cropped images
            ], [
                'name.required' => 'Court name is required.',
                'location.required' => 'Court address is required.',
                'latitude.required' => 'Latitude is required.',
                'latitude.between' => 'Latitude must be between -90 and 90.',
                'longitude.required' => 'Longitude is required.',
                'longitude.between' => 'Longitude must be between -180 and 180.',
                'city.required' => 'City is required.',
                'state.required' => 'State is required.',
                'zip.required' => 'ZIP code is required.',
                'images.*.image' => 'All uploaded files must be images.',
                'images.*.mimes' => 'Images must be jpeg, png, jpg, or gif format.',
                'images.*.max' => 'Each image must not exceed 5MB.',
            ]);

            if ($validator->fails()) {
                return back()->withErrors($validator)->withInput();
            }

            try {
                DB::beginTransaction();

                // Prepare court data
                $amenities = $request->amenities ? '"' . implode(',', $request->amenities) . '"' : null;
$nets = $request->nets ? '"' . implode(',', $request->nets) . '"' : null;

                $courtData = [
                    'user_id' => auth()->id(),
                    'name' => $request->name,
                    'location' => $request->location,
                    'latitude' => $request->latitude,
                    'longitude' => $request->longitude,
                    'city' => $request->city,
                    'state' => $request->state,
                    'zip' => $request->zip,
                    'description' => $request->description,
                    'phone' => $request->phone,
                    'email' => $request->email,
                    'website' => $request->website,
                  'amenities' => $amenities,
    'surfaces' => $request->surfaces,
    'nets' => $nets,
                    'no_indoor_courts' => $request->no_indoor_courts ?? 0,
                    'no_outdoor_courts' => $request->no_outdoor_courts ?? 0,
                    'status' => 1, // Active by default
                ];

                // Create the court
                $court = $this->module->create($courtData);

                // Handle image uploads
                $hasCroppedImages = $request->has('cropped_images') &&
                    is_array($request->cropped_images) &&
                    !empty(array_filter($request->cropped_images, function ($img) {
                        return !empty($img);
                    }));

                // Process images intelligently - avoid duplicates
                $processedImages = false;

                if ($hasCroppedImages) {
                    $this->handleCroppedImages($court, $request->cropped_images);
                    $processedImages = true;
                    Log::info('Processed cropped images for court', ['court_id' => $court->id]);
                }

                if ($request->hasFile('images')) {
                    // Only process regular images that weren't cropped
                    $croppedIndexes = [];
                    if ($hasCroppedImages) {
                        foreach ($request->cropped_images as $index => $croppedImage) {
                            if (!empty($croppedImage)) {
                                $croppedIndexes[] = $index;
                            }
                        }
                    }

                    $this->handleRegularImages($court, $request->file('images'), $croppedIndexes);
                    $processedImages = true;
                    Log::info('Processed regular images for court', [
                        'court_id' => $court->id,
                        'skipped_cropped_indexes' => $croppedIndexes
                    ]);
                }

                if (!$processedImages) {
                    // Log for debugging
                    Log::info('No images to process', [
                        'has_cropped' => $request->has('cropped_images'),
                        'cropped_is_array' => is_array($request->cropped_images ?? null),
                        'has_files' => $request->hasFile('images'),
                        'court_id' => $court->id
                    ]);
                }

                DB::commit();

                return redirect()->route('courts.my-courts')
                    ->with('success', $this->data['module_name'] . ' created successfully with all details and media');
            } catch (\Exception $e) {
                DB::rollBack();
                Log::error('Court creation failed: ' . $e->getMessage(), [
                    'user_id' => auth()->id(),
                    'request_data' => $request->except(['images', 'cropped_images'])
                ]);

                return back()->with('error', 'Failed to create court. Please try again.')
                    ->withInput();
            }
        }

        $this->data['page'] = 'Create Court';
        $this->data['google_api_key'] = config('services.google.places_api_key');

        return view($this->data['view_directory'] . '.create-advanced', $this->data);
    }

    /**
     * Handle cropped images from the frontend
     */
    private function handleCroppedImages($court, $croppedImages)
    {
        $mediaCount = 0;

        // Check if there are any existing media records for this court
        $existingMediaCount = CourtMedia::where('court_id', $court->id)->count();

        foreach ($croppedImages as $index => $croppedImage) {
            if (empty($croppedImage)) continue;

            try {
                // Remove data:image/jpeg;base64, prefix
                $imageData = explode(',', $croppedImage)[1];
                $imageData = base64_decode($imageData);

                // Generate unique filename
                $filename = 'court_' . $court->id . '_' . time() . '_' . $index . '.jpg';
                $relativePath = 'courts/' . $court->id . '/' . $filename;

                // Store the image using custom uploads disk
                Storage::disk(env('UPLOADS_DISK'))->put($relativePath, $imageData);

                // Create media record
                CourtMedia::create([
                    'court_id' => $court->id,
                    'file_name' => $filename,
                    'file_path' => $relativePath,
                    'file_type' => 'image',
                    'mime_type' => 'image/jpeg',
                    'file_size' => strlen($imageData),
                    'is_primary' => ($existingMediaCount + $mediaCount) === 0, // First overall image is primary
                    'status' => 1
                ]);

                $mediaCount++;
            } catch (\Exception $e) {
                Log::error('Failed to process cropped image: ' . $e->getMessage());
                continue;
            }
        }
    }

    /**
     * Handle regular image uploads
     */
    private function handleRegularImages($court, $images, $croppedIndexes = [])
    {
        $mediaCount = 0;

        // Check if there are any existing media records for this court
        $existingMediaCount = CourtMedia::where('court_id', $court->id)->count();

        Log::info('Processing regular images', [
            'court_id' => $court->id,
            'image_count' => count($images),
            'existing_media_count' => $existingMediaCount,
            'cropped_indexes' => $croppedIndexes
        ]);

        foreach ($images as $index => $image) {
            // Skip this image if it was already processed as a cropped image
            if (in_array($index, $croppedIndexes)) {
                Log::info('Skipping regular image - already processed as cropped', [
                    'court_id' => $court->id,
                    'index' => $index
                ]);
                continue;
            }

            try {
                // Generate unique filename
                $filename = 'court_' . $court->id . '_' . time() . '_' . $index . '.' . $image->getClientOriginalExtension();
                $relativePath = 'courts/' . $court->id . '/' . $filename;

                // Store the image using custom uploads disk
                $image->storeAs('courts/' . $court->id, $filename, env('UPLOADS_DISK'));

                // Create media record
                $courtMedia = CourtMedia::create([
                    'court_id' => $court->id,
                    'file_name' => $filename,
                    'file_path' => $relativePath,
                    'file_type' => 'image',
                    'mime_type' => $image->getMimeType(),
                    'file_size' => $image->getSize(),
                    'is_primary' => ($existingMediaCount + $mediaCount) === 0, // First overall image is primary
                    'status' => 1
                ]);

                Log::info('Regular image processed successfully', [
                    'court_id' => $court->id,
                    'index' => $index,
                    'filename' => $filename,
                    'media_id' => $courtMedia->id,
                    'is_primary' => ($existingMediaCount + $mediaCount) === 0
                ]);

                $mediaCount++;
            } catch (\Exception $e) {
                Log::error('Failed to process regular image: ' . $e->getMessage(), [
                    'court_id' => $court->id,
                    'index' => $index,
                    'filename' => $filename ?? 'unknown',
                    'error' => $e->getTraceAsString()
                ]);
                continue;
            }
        }

        Log::info('Finished processing regular images', [
            'court_id' => $court->id,
            'processed_count' => $mediaCount,
            'skipped_count' => count($croppedIndexes)
        ]);
    }

    public function edit(Request $request, $id)
    {
        if ($request->isMethod('post')) {
            $validatedData = $request->validate([
                'club_id'       => 'required|string',
                'name'       => 'required|string',
            ]);

            $club_id = $request->club_id;

            $court = $this->module->where('id', $id)->update($validatedData);

            return redirect()->route('courts.index', ['club_id' => $club_id])->with('success', $this->data['module_name'] . ' updated successfully');
        }
        $this->data['clubs'] = Club::all();
        $this->data['court'] = Court::find($id);
        return view($this->data['view_directory'] . '.' . __FUNCTION__, $this->data);
    }

    public function status($id)
    {
        $club = $this->module::find($id);
        $club->status = $club->status ? '0' : '1';
        $club->save();

        return redirect()->back()->with('success', $this->data['module_name'] . ' status updated successfully');
    }

    public function delete($id)
    {
        $user = $this->module::find($id);

        if ($user) {
            $user->delete();

            return redirect()->back()->with('success', $this->data['module_name'] . ' deleted successfully');
        }

        return redirect()->back()->with('error', 'User not found');
    }

    /**
     * Display courts created by the authenticated user
     */
    public function myCourts(Request $request)
    {
        if ($request->ajax()) {
            $data = $this->module::query();

            return DataTables::of($data)
                ->addIndexColumn()
                ->addColumn('courts_count', function ($row) {
                    $indoor = (int)($row->no_indoor_courts ?? 0);
                    $outdoor = (int)($row->no_outdoor_courts ?? 0);
                    $total = $indoor + $outdoor;
                    return $total;
                })
                ->addColumn('action', function ($row) {
                    return '<a href="' . route("courts.edit", ['id' => $row->id]) . '" class="btn btn-primary btn-sm">Edit</a>';
                })
                ->make(true);
        }

        $this->data['page'] = 'All Courts';
        $this->data['total_courts'] = $this->module::count();
        $this->data['active_courts'] = $this->module::where('status', 1)->count();
        $this->data['inactive_courts'] = $this->data['total_courts'] - $this->data['active_courts'];

        return view($this->data['view_directory'] . '.my-courts', $this->data);
    }
}
