<?php

namespace App\Http\Controllers;

use App\Models\BookingType;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Validator;

class BookingTypeController extends Controller
{
    /**
     * Display a listing of the resource.
     */
    public function index(Request $request): JsonResponse
    {
        try {
            $query = BookingType::query();

            // Filter by active status
            if ($request->has('active_only') && $request->boolean('active_only')) {
                $query->active();
            }

            // Filter by requires contract
            if ($request->has('requires_contract')) {
                $query->where('requires_contract', $request->boolean('requires_contract'));
            }

            // Filter by duration range
            if ($request->has('min_duration')) {
                $query->where('min_duration_days', '<=', $request->get('min_duration'));
            }

            if ($request->has('max_duration')) {
                $query->where(function ($q) use ($request) {
                    $q->whereNull('max_duration_days')
                        ->orWhere('max_duration_days', '>=', $request->get('max_duration'));
                });
            }

            // Search by name
            if ($request->has('search')) {
                $search = $request->get('search');
                $query->where('type_name', 'like', "%{$search}%");
            }

            // Order by
            $orderBy = $request->get('order_by', 'type_name');
            $orderDirection = $request->get('order_direction', 'asc');
            $query->orderBy($orderBy, $orderDirection);

            // Get all or paginate
            if ($request->has('paginate') && !$request->boolean('paginate')) {
                $bookingTypes = $query->get();
            } else {
                $perPage = $request->get('per_page', 15);
                $bookingTypes = $query->paginate($perPage);
            }

            return response()->json([
                'success' => true,
                'data' => $bookingTypes
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to fetch booking types',
                'error' => config('app.debug') ? $e->getMessage() : null
            ], 500);
        }
    }

    /**
     * Store a newly created resource in storage.
     */
    public function store(Request $request): JsonResponse
    {
        try {
            // ✅ SIMPLE AUTHENTICATION CHECK - NO PERMISSION CHECK
            if (!$request->user()) {
                return response()->json([
                    'success' => false,
                    'message' => 'Unauthenticated'
                ], 401);
            }

            $validator = Validator::make($request->all(), [
                'type_name' => 'required|string|max:100|unique:booking_types,type_name',
                'type_description' => 'nullable|string',
                'min_duration_days' => 'required|integer|min:1',
                'max_duration_days' => 'nullable|integer|min:1',
                'requires_contract' => 'boolean',
                'is_active' => 'boolean'
            ]);

            if ($validator->fails()) {
                return response()->json([
                    'success' => false,
                    'message' => 'Validation failed',
                    'errors' => $validator->errors()
                ], 422);
            }

            $validated = $validator->validated();

            // Validate max duration is greater than min duration
            if (
                isset($validated['max_duration_days']) &&
                $validated['max_duration_days'] < $validated['min_duration_days']
            ) {
                return response()->json([
                    'success' => false,
                    'message' => 'Max duration must be greater than or equal to min duration',
                    'errors' => ['max_duration_days' => ['Max duration must be greater than min duration']]
                ], 422);
            }

            $bookingType = BookingType::create($validated);

            return response()->json([
                'success' => true,
                'message' => 'Booking type created successfully',
                'data' => $bookingType
            ], 201);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to create booking type',
                'error' => config('app.debug') ? $e->getMessage() : null
            ], 500);
        }
    }

    /**
     * Display the specified resource.
     */
    public function show(Request $request, string $id): JsonResponse
    {
        try {
            $bookingType = BookingType::find($id);

            if (!$bookingType) {
                return response()->json([
                    'success' => false,
                    'message' => 'Booking type not found'
                ], 404);
            }

            return response()->json([
                'success' => true,
                'data' => $bookingType
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to fetch booking type',
                'error' => config('app.debug') ? $e->getMessage() : null
            ], 500);
        }
    }

    /**
     * Update the specified resource in storage.
     */
    public function update(Request $request, string $id): JsonResponse
    {
        try {
            // ✅ SIMPLE AUTHENTICATION CHECK - NO PERMISSION CHECK
            if (!$request->user()) {
                return response()->json([
                    'success' => false,
                    'message' => 'Unauthenticated'
                ], 401);
            }

            $bookingType = BookingType::find($id);

            if (!$bookingType) {
                return response()->json([
                    'success' => false,
                    'message' => 'Booking type not found'
                ], 404);
            }

            $validator = Validator::make($request->all(), [
                'type_name' => 'sometimes|string|max:100|unique:booking_types,type_name,' . $id . ',type_id',
                'type_description' => 'nullable|string',
                'min_duration_days' => 'sometimes|integer|min:1',
                'max_duration_days' => 'nullable|integer|min:1',
                'requires_contract' => 'boolean',
                'is_active' => 'boolean'
            ]);

            if ($validator->fails()) {
                return response()->json([
                    'success' => false,
                    'message' => 'Validation failed',
                    'errors' => $validator->errors()
                ], 422);
            }

            $validated = $validator->validated();

            // Validate max duration is greater than min duration
            if (
                isset($validated['max_duration_days']) &&
                isset($validated['min_duration_days']) &&
                $validated['max_duration_days'] < $validated['min_duration_days']
            ) {
                return response()->json([
                    'success' => false,
                    'message' => 'Max duration must be greater than or equal to min duration',
                    'errors' => ['max_duration_days' => ['Max duration must be greater than min duration']]
                ], 422);
            }

            $bookingType->update($validated);

            return response()->json([
                'success' => true,
                'message' => 'Booking type updated successfully',
                'data' => $bookingType
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to update booking type',
                'error' => config('app.debug') ? $e->getMessage() : null
            ], 500);
        }
    }

    /**
     * Remove the specified resource from storage.
     */
    public function destroy(Request $request, string $id): JsonResponse
    {
        try {
            // ✅ SIMPLE AUTHENTICATION CHECK - NO PERMISSION CHECK
            if (!$request->user()) {
                return response()->json([
                    'success' => false,
                    'message' => 'Unauthenticated'
                ], 401);
            }

            $bookingType = BookingType::find($id);

            if (!$bookingType) {
                return response()->json([
                    'success' => false,
                    'message' => 'Booking type not found'
                ], 404);
            }

            // Check if booking type is being used (you might want to add this check)
            // if ($bookingType->bookings()->exists()) {
            //     return response()->json([
            //         'success' => false,
            //         'message' => 'Cannot delete booking type that is in use'
            //     ], 422);
            // }

            $bookingType->delete();

            return response()->json([
                'success' => true,
                'message' => 'Booking type deleted successfully'
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to delete booking type',
                'error' => config('app.debug') ? $e->getMessage() : null
            ], 500);
        }
    }

    /**
     * Get booking types by duration
     */
    public function getByDuration(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'duration_days' => 'required|integer|min:1'
            ]);

            if ($validator->fails()) {
                return response()->json([
                    'success' => false,
                    'message' => 'Validation failed',
                    'errors' => $validator->errors()
                ], 422);
            }

            $durationDays = $request->get('duration_days');
            $bookingTypes = BookingType::getAvailableForDuration($durationDays);

            return response()->json([
                'success' => true,
                'data' => $bookingTypes
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to fetch booking types by duration',
                'error' => config('app.debug') ? $e->getMessage() : null
            ], 500);
        }
    }

    /**
     * Get active booking types list
     */
    public function getActiveTypes(): JsonResponse
    {
        try {
            $bookingTypes = BookingType::active()
                ->orderBy('type_name')
                ->get();

            return response()->json([
                'success' => true,
                'data' => $bookingTypes
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to fetch active booking types',
                'error' => config('app.debug') ? $e->getMessage() : null
            ], 500);
        }
    }

    /**
     * Validate duration for booking type
     */
    public function validateDuration(Request $request, string $id): JsonResponse
    {
        try {
            $bookingType = BookingType::find($id);

            if (!$bookingType) {
                return response()->json([
                    'success' => false,
                    'message' => 'Booking type not found'
                ], 404);
            }

            $validator = Validator::make($request->all(), [
                'duration_days' => 'required|integer|min:1'
            ]);

            if ($validator->fails()) {
                return response()->json([
                    'success' => false,
                    'message' => 'Validation failed',
                    'errors' => $validator->errors()
                ], 422);
            }

            $durationDays = $request->get('duration_days');
            $isValid = $bookingType->isValidDuration($durationDays);

            return response()->json([
                'success' => true,
                'data' => [
                    'is_valid' => $isValid,
                    'booking_type' => $bookingType,
                    'duration_days' => $durationDays,
                    'message' => $isValid ?
                        'Duration is valid for this booking type' :
                        'Duration is not valid for this booking type'
                ]
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to validate duration',
                'error' => config('app.debug') ? $e->getMessage() : null
            ], 500);
        }
    }
}
