<?php

namespace App\Http\Controllers\Agency\Tour;

use App\Http\Controllers\Controller;
use App\Models\Tour\Tour;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;

class TourDateController extends Controller
{
    use AuthorizesRequests;

    public function index(Tour $tour)
    {
        $this->authorize('update', $tour);

        $dates = $tour->tourDates()
            ->with(['tourPricing', 'assignedGuide', 'assignedVehicle'])
            ->orderBy('start_date')
            ->get();

        $pricings = $tour->pricings()->active()->get();
        $activeCurrencies = auth()->user()->agency->getActiveCurrencies();

        return view('agency.products.kultur-turlari.dates', compact('tour', 'dates', 'pricings', 'activeCurrencies'));
    }

    public function store(Request $request, Tour $tour)
    {
        $this->authorize('update', $tour);

        $activeCurrencies = auth()->user()->agency->getActiveCurrencies();
        $allowedCurrencies = $activeCurrencies->pluck('code')->toArray();

        $validator = Validator::make($request->all(), [
            'start_date' => 'required|date|after:today',
            'end_date' => 'required|date|after_or_equal:start_date',
            'start_time' => 'nullable|date_format:H:i',
            'end_time' => 'nullable|date_format:H:i',
            'total_capacity' => 'required|integer|min:1',
            'adult_capacity' => 'nullable|integer|min:0',
            'child_capacity' => 'nullable|integer|min:0',
            'infant_capacity' => 'nullable|integer|min:0',
            'adult_price' => 'nullable|numeric|min:0',
            'child_price' => 'nullable|numeric|min:0',
            'infant_price' => 'nullable|numeric|min:0',
            'child_min_age' => 'nullable|integer|min:0|max:17',
            'child_max_age' => 'nullable|integer|min:1|max:18',
            'infant_max_age' => 'nullable|integer|min:0|max:5',
            'currency' => 'required|in:' . implode(',', $allowedCurrencies),
            'early_booking_discount' => 'nullable|numeric|min:0|max:100',
            'last_minute_discount' => 'nullable|numeric|min:0|max:100',
            'group_discount' => 'nullable|numeric|min:0|max:100',
            'special_discount' => 'nullable|numeric|min:0|max:100',
            'season_type' => 'required|in:low,medium,high,peak',
            'status' => 'required|in:draft,published,booking_open,booking_closed,confirmed,in_progress,completed,cancelled',
            'min_participants' => 'nullable|integer|min:0',
            'tour_pricing_id' => 'nullable|exists:tour_pricings,id',
            'special_notes' => 'nullable|string|max:1000',
        ], [
            'start_date.required' => 'Başlangıç tarihi zorunludur.',
            'start_date.date' => 'Geçerli bir başlangıç tarihi giriniz.',
            'start_date.after' => 'Başlangıç tarihi bugünden sonra olmalıdır.',
            'end_date.required' => 'Bitiş tarihi zorunludur.',
            'end_date.date' => 'Geçerli bir bitiş tarihi giriniz.',
            'end_date.after_or_equal' => 'Bitiş tarihi başlangıç tarihinden önce olamaz.',
            'start_time.date_format' => 'Geçerli bir başlangıç saati giriniz (ÖR: 09:00).',
            'end_time.date_format' => 'Geçerli bir bitiş saati giriniz (ÖR: 18:00).',
            'total_capacity.required' => 'Toplam kapasite zorunludur.',
            'total_capacity.integer' => 'Toplam kapasite sayı olmalıdır.',
            'total_capacity.min' => 'Toplam kapasite en az 1 olmalıdır.',
            'adult_capacity.integer' => 'Yetişkin kapasitesi sayı olmalıdır.',
            'child_capacity.integer' => 'Çocuk kapasitesi sayı olmalıdır.',
            'infant_capacity.integer' => 'Bebek kapasitesi sayı olmalıdır.',
            'adult_price.numeric' => 'Yetişkin fiyatı sayı olmalıdır.',
            'adult_price.min' => 'Yetişkin fiyatı negatif olamaz.',
            'child_price.numeric' => 'Çocuk fiyatı sayı olmalıdır.',
            'child_price.min' => 'Çocuk fiyatı negatif olamaz.',
            'infant_price.numeric' => 'Bebek fiyatı sayı olmalıdır.',
            'infant_price.min' => 'Bebek fiyatı negatif olamaz.',
            'currency.required' => 'Para birimi zorunludur.',
            'currency.in' => 'Geçersiz para birimi seçimi.',
            'early_booking_discount.numeric' => 'Erken rezervasyon indirimi sayı olmalıdır.',
            'early_booking_discount.min' => 'Erken rezervasyon indirimi negatif olamaz.',
            'early_booking_discount.max' => 'Erken rezervasyon indirimi %100\'den fazla olamaz.',
            'last_minute_discount.numeric' => 'Son dakika indirimi sayı olmalıdır.',
            'last_minute_discount.min' => 'Son dakika indirimi negatif olamaz.',
            'last_minute_discount.max' => 'Son dakika indirimi %100\'den fazla olamaz.',
            'group_discount.numeric' => 'Grup indirimi sayı olmalıdır.',
            'group_discount.min' => 'Grup indirimi negatif olamaz.',
            'group_discount.max' => 'Grup indirimi %100\'den fazla olamaz.',
            'special_discount.numeric' => 'Özel indirim sayı olmalıdır.',
            'special_discount.min' => 'Özel indirim negatif olamaz.',
            'special_discount.max' => 'Özel indirim %100\'den fazla olamaz.',
            'season_type.required' => 'Sezon tipi zorunludur.',
            'season_type.in' => 'Geçersiz sezon tipi seçimi.',
            'status.required' => 'Durum zorunludur.',
            'status.in' => 'Geçersiz durum seçimi.',
            'min_participants.integer' => 'Minimum katılımcı sayısı tam sayı olmalıdır.',
            'min_participants.min' => 'Minimum katılımcı sayısı negatif olamaz.',
            'tour_pricing_id.exists' => 'Seçilen fiyatlandırma planı bulunamadı.',
            'special_notes.string' => 'Özel notlar metin olmalıdır.',
            'special_notes.max' => 'Özel notlar en fazla 1000 karakter olabilir.',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'errors' => $validator->errors(),
                'message' => 'Lütfen tüm alanları doğru şekilde doldurunuz.'
            ], 422);
        }

        $data = $request->all();
        $data['tour_id'] = $tour->id;
        $data['remaining_capacity'] = $request->total_capacity;

        // Checkboxlar
        $data['is_active'] = $request->has('is_active');
        $data['is_published'] = !in_array($request->status, ['draft']);
        $data['is_bookable'] = $request->has('is_bookable');
        $data['guarantee_departure'] = $request->has('is_active');

        // Duration hesapla
        $startDate = \Carbon\Carbon::parse($request->start_date);
        $endDate = \Carbon\Carbon::parse($request->end_date);
        $data['duration_days'] = $startDate->diffInDays($endDate) + 1;
        $data['duration_nights'] = max(0, $data['duration_days'] - 1);

        // Code oluştur
        $data['code'] = 'TD' . date('Ymd') . str_pad($tour->tourDates()->count() + 1, 4, '0', STR_PAD_LEFT);

        $tourDate = $tour->tourDates()->create($data);

        return response()->json([
            'success' => true,
            'tourDate' => $tourDate->load(['tourPricing']),
            'message' => 'Tur tarihi başarıyla eklendi.'
        ]);
    }

    public function show(Request $request, Tour $tour, $dateId)
    {
        $this->authorize('update', $tour);

        $tourDate = $tour->tourDates()
            ->with(['tourPricing', 'assignedGuide', 'assignedVehicle'])
            ->find($dateId);

        if (!$tourDate) {
            return response()->json([
                'success' => false,
                'message' => 'Tarih bulunamadı.'
            ], 404);
        }

        $dateData = $tourDate->toArray();

        if ($tourDate->start_date) {
            $dateData['start_date'] = $tourDate->start_date->format('Y-m-d');
        }

        if ($tourDate->end_date) {
            $dateData['end_date'] = $tourDate->end_date->format('Y-m-d');
        }

        if ($tourDate->start_time) {
            $dateData['start_time'] = $tourDate->start_time->format('H:i');
        }

        if ($tourDate->end_time) {
            $dateData['end_time'] = $tourDate->end_time->format('H:i');
        }

        return response()->json([
            'success' => true,
            'date' => $dateData
        ]);
    }

    public function update(Request $request, Tour $tour, $date)
    {
        $this->authorize('update', $tour);

        $tourDate = $tour->tourDates()->findOrFail($date);

        $activeCurrencies = auth()->user()->agency->getActiveCurrencies();
        $allowedCurrencies = $activeCurrencies->pluck('code')->toArray();

        $validator = Validator::make($request->all(), [
            'start_date' => 'required|date',
            'end_date' => 'required|date|after_or_equal:start_date',
            'start_time' => 'nullable|date_format:H:i',
            'end_time' => 'nullable|date_format:H:i',
            'total_capacity' => 'required|integer|min:1',
            'adult_capacity' => 'nullable|integer|min:0',
            'child_capacity' => 'nullable|integer|min:0',
            'infant_capacity' => 'nullable|integer|min:0',
            'adult_price' => 'nullable|numeric|min:0',
            'child_price' => 'nullable|numeric|min:0',
            'infant_price' => 'nullable|numeric|min:0',
            'child_min_age' => 'nullable|integer|min:0|max:17',
            'child_max_age' => 'nullable|integer|min:1|max:18',
            'infant_max_age' => 'nullable|integer|min:0|max:5',
            'currency' => 'required|in:' . implode(',', $allowedCurrencies),
            'early_booking_discount' => 'nullable|numeric|min:0|max:100',
            'last_minute_discount' => 'nullable|numeric|min:0|max:100',
            'group_discount' => 'nullable|numeric|min:0|max:100',
            'special_discount' => 'nullable|numeric|min:0|max:100',
            'season_type' => 'required|in:low,medium,high,peak',
            'status' => 'required|in:draft,published,booking_open,booking_closed,confirmed,in_progress,completed,cancelled',
            'min_participants' => 'nullable|integer|min:0',
            'tour_pricing_id' => 'nullable|exists:tour_pricings,id',
            'special_notes' => 'nullable|string|max:1000',
        ], [
            'start_date.required' => 'Başlangıç tarihi zorunludur.',
            'start_date.date' => 'Geçerli bir başlangıç tarihi giriniz.',
            'end_date.required' => 'Bitiş tarihi zorunludur.',
            'end_date.date' => 'Geçerli bir bitiş tarihi giriniz.',
            'end_date.after_or_equal' => 'Bitiş tarihi başlangıç tarihinden önce olamaz.',
            'start_time.date_format' => 'Geçerli bir başlangıç saati giriniz (ÖR: 09:00).',
            'end_time.date_format' => 'Geçerli bir bitiş saati giriniz (ÖR: 18:00).',
            'total_capacity.required' => 'Toplam kapasite zorunludur.',
            'total_capacity.integer' => 'Toplam kapasite sayı olmalıdır.',
            'total_capacity.min' => 'Toplam kapasite en az 1 olmalıdır.',
            'currency.required' => 'Para birimi zorunludur.',
            'currency.in' => 'Geçersiz para birimi seçimi.',
            'season_type.required' => 'Sezon tipi zorunludur.',
            'season_type.in' => 'Geçersiz sezon tipi seçimi.',
            'status.required' => 'Durum zorunludur.',
            'status.in' => 'Geçersiz durum seçimi.',
            'special_notes.max' => 'Özel notlar en fazla 1000 karakter olabilir.',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'errors' => $validator->errors(),
                'message' => 'Lütfen tüm alanları doğru şekilde doldurunuz.'
            ], 422);
        }

        $data = $request->all();

        // Checkboxlar
        $data['is_active'] = $request->has('is_active');
        $data['is_published'] = !in_array($request->status, ['draft']);
        $data['is_bookable'] = $request->has('is_bookable');
        $data['guarantee_departure'] = $request->has('guarantee_departure');

        // Duration hesapla
        $startDate = \Carbon\Carbon::parse($request->start_date);
        $endDate = \Carbon\Carbon::parse($request->end_date);
        $data['duration_days'] = $startDate->diffInDays($endDate) + 1;
        $data['duration_nights'] = max(0, $data['duration_days'] - 1);

        // Kapasite güncellendi mi kontrol et
        if ($request->total_capacity != $tourDate->total_capacity) {
            $data['remaining_capacity'] = $request->total_capacity - $tourDate->sold_count - $tourDate->reserved_count;
        }

        $tourDate->update($data);

        return response()->json([
            'success' => true,
            'message' => 'Tur tarihi başarıyla güncellendi.'
        ]);
    }

    public function destroy(Tour $tour, $date)
    {
        $this->authorize('update', $tour);

        $tourDate = $tour->tourDates()->findOrFail($date);

        if ($tourDate->sold_count > 0) {
            return response()->json([
                'success' => false,
                'message' => 'Satışı olan tur tarihi silinemez.'
            ], 422);
        }

        $tourDate->delete();

        return response()->json([
            'success' => true,
            'message' => 'Tur tarihi başarıyla silindi.'
        ]);
    }

    public function toggleStatus(Tour $tour, $date)
    {
        $this->authorize('update', $tour);

        $tourDate = $tour->tourDates()->findOrFail($date);
        $tourDate->update(['is_active' => !$tourDate->is_active]);

        return response()->json([
            'success' => true,
            'is_active' => $tourDate->is_active,
            'message' => $tourDate->is_active ? 'Tur tarihi aktif edildi.' : 'Tur tarihi pasif edildi.'
        ]);
    }

    public function getPricingDefaults(Tour $tour)
    {
        $this->authorize('update', $tour);

        $defaultPricing = $tour->defaultPricing;

        if (!$defaultPricing) {
            $defaultPricing = $tour->pricings()->active()->first();
        }

        return response()->json([
            'success' => true,
            'pricing' => $defaultPricing
        ]);
    }
}
