<?php

namespace App\Http\Controllers\Agency\DayTour;

use App\Http\Controllers\Controller;
use App\Models\DayTour\DayTour;
use App\Models\Definition\Definition;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;

class DayTourDateController extends Controller
{
    use AuthorizesRequests;

    public function index(DayTour $tour)
    {
        $tourDates = $tour->tourDates()
            ->orderBy('tour_date', 'asc')
            ->paginate(20)
            ->withQueryString();

        // Get vehicles from definitions
        $vehicles = Definition::byAgency(Auth::user()->currentAgencyId())
            ->whereHas('definitionType', fn($q) => $q->where('name', 'vehicle'))
            ->active()
            ->orderBy('name')
            ->get();

        return view('agency.products.gunubirlik-turlar.dates', compact('tour', 'tourDates', 'vehicles'));
    }

    public function generate(Request $request, DayTour $tour)
    {
        $request->validate([
            'start_date' => 'required|date',
            'end_date' => 'required|date|after_or_equal:start_date',
            'action' => 'nullable|in:skip,update_prices,recreate',
            'outdated_action' => 'nullable|in:keep,deactivate,delete',
        ]);

        if (empty($tour->recurring_days)) {
            return response()->json([
                'success' => false,
                'message' => 'Tekrar eden günler tanımlanmamış. Lütfen önce genel bilgilerde gün seçimi yapın.'
            ]);
        }

        DB::beginTransaction();
        try {
            $startDate = \Carbon\Carbon::parse($request->start_date);
            $endDate = \Carbon\Carbon::parse($request->end_date);

            // Map English day names to lowercase format used in recurring_days
            $dayMapping = [
                'Monday' => 'monday',
                'Tuesday' => 'tuesday',
                'Wednesday' => 'wednesday',
                'Thursday' => 'thursday',
                'Friday' => 'friday',
                'Saturday' => 'saturday',
                'Sunday' => 'sunday',
            ];

            // First pass: collect dates that would be created
            $currentDate = $startDate->copy();
            $datesToCreate = [];
            $existingDates = [];
            $outdatedDates = []; // Dates no longer in recurring_days

            while ($currentDate->lte($endDate)) {
                $dayName = $dayMapping[$currentDate->format('l')];
                $dateString = $currentDate->format('Y-m-d');
                $existing = $tour->tourDates()->where('tour_date', $dateString)->first();

                if (in_array($dayName, $tour->recurring_days)) {
                    // This day is in current recurring_days
                    if ($existing) {
                        $existingDates[] = [
                            'id' => $existing->id,
                            'date' => $dateString,
                            'has_bookings' => $existing->booked_seats > 0
                        ];
                    } else {
                        $datesToCreate[] = $dateString;
                    }
                } else {
                    // This day is NOT in current recurring_days, but has an existing date
                    if ($existing) {
                        $outdatedDates[] = [
                            'id' => $existing->id,
                            'date' => $dateString,
                            'day_name' => $dayName,
                            'has_bookings' => $existing->booked_seats > 0
                        ];
                    }
                }

                $currentDate->addDay();
            }

            // If there are existing dates or outdated dates and no action specified, ask user
            if ((count($existingDates) > 0 || count($outdatedDates) > 0) && !$request->action) {
                DB::rollback();
                return response()->json([
                    'success' => false,
                    'needs_confirmation' => true,
                    'existing_dates' => $existingDates,
                    'outdated_dates' => $outdatedDates,
                    'new_dates' => $datesToCreate,
                    'message' => count($existingDates) . ' tarih zaten mevcut. Ne yapmak istersiniz?'
                ]);
            }

            // Process based on action
            $createdCount = 0;
            $updatedCount = 0;
            $skippedCount = 0;
            $deletedCount = 0;
            $deactivatedCount = 0;
            $action = $request->action ?? 'skip';
            $outdatedAction = $request->outdated_action ?? 'keep';

            // Handle outdated dates (dates no longer in recurring_days)
            foreach ($outdatedDates as $outdatedDate) {
                if ($outdatedAction === 'keep') {
                    // Do nothing
                } elseif ($outdatedAction === 'deactivate') {
                    $tour->tourDates()->where('id', $outdatedDate['id'])->update(['is_active' => false]);
                    $deactivatedCount++;
                } elseif ($outdatedAction === 'delete') {
                    if ($outdatedDate['has_bookings']) {
                        // Don't delete if has bookings, just deactivate
                        $tour->tourDates()->where('id', $outdatedDate['id'])->update(['is_active' => false]);
                        $deactivatedCount++;
                    } else {
                        $tour->tourDates()->where('id', $outdatedDate['id'])->delete();
                        $deletedCount++;
                    }
                }
            }

            // Handle existing dates based on action
            foreach ($existingDates as $existingDate) {
                if ($action === 'skip') {
                    $skippedCount++;
                } elseif ($action === 'update_prices') {
                    $tour->tourDates()->where('id', $existingDate['id'])->update([
                        'adult_price' => $tour->adult_price,
                        'child_price' => $tour->child_price,
                        'infant_price' => $tour->infant_price,
                    ]);
                    $updatedCount++;
                } elseif ($action === 'recreate') {
                    if ($existingDate['has_bookings']) {
                        $skippedCount++;
                    } else {
                        $tour->tourDates()->where('id', $existingDate['id'])->delete();
                        $datesToCreate[] = $existingDate['date'];
                        $deletedCount++;
                    }
                }
            }

            // Create new dates
            foreach ($datesToCreate as $dateString) {
                $tour->tourDates()->create([
                    'tour_date' => $dateString,
                    'start_time' => $tour->start_time,
                    'end_time' => $tour->end_time,
                    'status' => 'available',
                    'is_active' => true,
                    'is_guaranteed' => false,
                    'max_participants' => $tour->max_participants,
                    'available_seats' => $tour->max_participants,
                    'booked_seats' => 0,
                    'reserved_seats' => 0,
                    'adult_price' => $tour->adult_price,
                    'child_price' => $tour->child_price,
                    'infant_price' => $tour->infant_price,
                ]);
                $createdCount++;
            }

            DB::commit();

            $message = [];
            if ($createdCount > 0) $message[] = "{$createdCount} tarih oluşturuldu";
            if ($updatedCount > 0) $message[] = "{$updatedCount} tarih fiyatı güncellendi";
            if ($deletedCount > 0) $message[] = "{$deletedCount} tarih silindi";
            if ($deactivatedCount > 0) $message[] = "{$deactivatedCount} tarih pasif edildi";
            if ($skippedCount > 0) $message[] = "{$skippedCount} tarih atlandı";

            return response()->json([
                'success' => true,
                'message' => implode(', ', $message) ?: 'İşlem tamamlandı'
            ]);

        } catch (\Exception $e) {
            DB::rollback();
            return response()->json([
                'success' => false,
                'message' => 'Tarihler oluşturulurken bir hata oluştu: ' . $e->getMessage()
            ]);
        }
    }

    public function updateVehicle(Request $request, DayTour $tour, $dateId)
    {
        $request->validate([
            'vehicle_id' => 'nullable|exists:definitions,id',
        ]);

        try {
            $date = $tour->tourDates()->findOrFail($dateId);
            $date->update(['vehicle_id' => $request->vehicle_id]);

            return response()->json([
                'success' => true,
                'message' => 'Araç ataması güncellendi.'
            ]);

        } catch (\Exception $e) {
            \Log::error('Vehicle update error: ' . $e->getMessage(), [
                'tour_id' => $tour->id,
                'date_id' => $dateId,
                'vehicle_id' => $request->vehicle_id,
                'trace' => $e->getTraceAsString()
            ]);

            return response()->json([
                'success' => false,
                'message' => 'Araç ataması güncellenirken bir hata oluştu: ' . $e->getMessage()
            ], 500);
        }
    }

    public function toggleStatus(DayTour $tour, $dateId)
    {
        try {
            $date = $tour->tourDates()->findOrFail($dateId);
            $date->update(['is_active' => !$date->is_active]);

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

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'İşlem başarısız oldu.'
            ], 500);
        }
    }

    public function destroy(DayTour $tour, $dateId)
    {
        try {
            $date = $tour->tourDates()->findOrFail($dateId);

            // Check if date has bookings
            if ($date->booked_seats > 0) {
                return response()->json([
                    'success' => false,
                    'message' => 'Bu tarihte rezervasyon bulunduğu için silinemez.'
                ], 400);
            }

            $date->delete();

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

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Tarih silinirken bir hata oluştu.'
            ], 500);
        }
    }
}
