<?php

namespace App\Http\Controllers\Agency\DayTour;

use App\Http\Controllers\Concerns\SyncsMarketplacePrices;
use App\Http\Controllers\Controller;
use App\Models\DayTour\DayTour;
use App\Models\Resource;
use App\Models\ResourceSchedule;
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;
    use SyncsMarketplacePrices;

    /** Günübirlik tarih satırının temel alanları ↔ pazaryeri fiyat alanları eşlemesi. */
    private array $baseFieldMap = [
        'adult_price'  => 'adult_price',
        'child_price'  => 'child_price',
        'infant_price' => 'infant_price',
    ];

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

        // Get vehicles from resources
        $vehicles = Resource::byAgency(Auth::user()->currentAgencyId())
            ->vehicles()
            ->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',
            'season_name' => 'nullable|string|max:80',
            'weekdays' => 'required|array|min:1',
            'weekdays.*' => 'in:monday,tuesday,wednesday,thursday,friday,saturday,sunday',
            'action' => 'nullable|in:skip,update_prices,recreate',
            'outdated_action' => 'nullable|in:keep,deactivate,delete',
        ], [
            'weekdays.required' => 'Lütfen turun yapılacağı günleri seçin.',
            'weekdays.min' => 'Lütfen en az bir gün seçin.',
        ]);

        $weekdays = array_values(array_unique($request->input('weekdays')));
        $seasonName = trim((string) $request->input('season_name', '')) ?: null;

        // Seçim, turun genel ayarındaki tekrar eden günlere de yazılır (tek kaynak orada kalsın)
        $tour->update(['recurring_days' => $weekdays]);

        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, $weekdays)) {
                    // This day is in the selected weekdays
                    if ($existing) {
                        $existingDates[] = [
                            'id' => $existing->id,
                            'date' => $dateString,
                            'has_bookings' => $existing->booked_seats > 0
                        ];
                    } else {
                        $datesToCreate[] = $dateString;
                    }
                } else {
                    // This day is NOT in the selected weekdays, 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(array_filter([
                        'adult_price' => $tour->adult_price,
                        'child_price' => $tour->child_price,
                        'infant_price' => $tour->infant_price,
                        // Sezon adı girildiyse mevcut tarih de bu sezona etiketlenir
                        'season_name' => $seasonName,
                    ], fn ($v) => $v !== null));
                    $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,
                    'season_name' => $seasonName,
                    '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:resources,id',
        ]);

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

            // Sync with resource schedule
            ResourceSchedule::where('reference_model_type', get_class($date))
                ->where('reference_model_id', $date->id)
                ->delete();

            if ($request->vehicle_id) {
                ResourceSchedule::create([
                    'resource_id' => $request->vehicle_id,
                    'agency_id' => auth()->user()->currentAgencyId(),
                    'start_date' => $date->tour_date->format('Y-m-d'),
                    'end_date' => $date->tour_date->format('Y-m-d'),
                    'start_time' => $date->start_time,
                    'end_time' => $date->end_time,
                    'schedule_type' => 'tour_assignment',
                    'title' => ($tour->name ?? 'Günübirlik Tur') . ' - Araç Görevi (' . ($date->vehicle?->name ?? 'Plakasız') . ')',
                    'description' => 'Günübirlik tur araç ataması',
                    'reference_model_type' => get_class($date),
                    'reference_model_id' => $date->id,
                    'is_approved' => true
                ]);
            }

            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);
        }
    }

    /** Bir günübirlik tarihine pazaryeri/para birimi bazlı fiyatları kaydeder. */
    public function updateMarketplacePrices(Request $request, DayTour $tour, $dateId)
    {
        $request->validate([
            'marketplace_prices' => 'nullable|array',
        ]);

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

        $agencyId = Auth::user()->currentAgencyId();
        $mpInput = $request->input('marketplace_prices', []);
        $this->syncMarketplacePrices($date, $mpInput, $agencyId);
        $this->applyPrimaryToDate($date, $mpInput, $agencyId, $this->baseFieldMap, $tour->product?->primary_marketplace_id);

        return response()->json([
            'success' => true,
            'message' => 'Pazaryeri fiyatları güncellendi.'
        ]);
    }

    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);
        }
    }
}
