<?php

namespace App\Http\Controllers\Agency\Tour;

use App\Http\Controllers\Controller;
use App\Models\Definition\City;
use App\Models\Definition\Definition;
use App\Models\Tour\Tour;
use App\Models\Product\ProductCategory;
use App\Models\Agency\Marketplace;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;

class TourController extends Controller
{
    use AuthorizesRequests;

    public function index(Request $request)
    {
        $query = Tour::with(['categories', 'departureCity', 'arrivalCity', 'defaultPricing'])
            ->byAgency(Auth::user()->currentAgencyId());

        // Filters
        if ($request->filled('search')) {
            $query->where(function ($q) use ($request) {
                $q->where('name', 'like', '%' . $request->search . '%')
                    ->orWhere('code', 'like', '%' . $request->search . '%')
                    ->orWhere('description', 'like', '%' . $request->search . '%');
            });
        }

        if ($request->filled('status')) {
            switch ($request->status) {
                case 'active':
                    $query->active();
                    break;
                case 'inactive':
                    $query->where('is_active', false);
                    break;
                case 'published':
                    $query->where('is_public', true);
                    break;
                case 'draft':
                    $query->where('is_public', false);
                    break;
            }
        }

        if ($request->filled('category')) {
            $query->whereHas('categories', function ($q) use ($request) {
                $q->where('product_categories.id', $request->category);
            });
        }

        if ($request->filled('tour_type')) {
            $query->where('tour_type', $request->tour_type);
        }

        // Sort
        $sortBy = $request->get('sort', 'created_at');
        $sortDir = $request->get('dir', 'desc');
        $query->orderBy($sortBy, $sortDir);

        $tours = $query->paginate(12)->withQueryString();

        // For filters - Get categories for "kultur-turu" product type
        $kulturTuruType = \App\Models\Product\ProductType::where('slug', 'kultur-turu')->first();
        $categories = ProductCategory::where('product_type_id', $kulturTuruType->id)
            ->where('agency_id', Auth::user()->currentAgencyId())
            ->active()
            ->orderBy('sort_order')
            ->get();

        return view('agency.products.kultur-turlari.index', compact('tours', 'categories'));
    }

    public function create()
    {
        // Get categories for "kultur-turu" product type
        $kulturTuruType = \App\Models\Product\ProductType::where('slug', 'kultur-turu')->first();
        $categories = ProductCategory::where('product_type_id', $kulturTuruType->id)
            ->where('agency_id', Auth::user()->currentAgencyId())
            ->active()
            ->orderBy('sort_order')
            ->get();

        $cities = City::orderBy('city')->get();

        $marketplaces = Marketplace::with(['languages', 'currencies'])
            ->where('agency_id', Auth::user()->currentAgencyId())
            ->where('is_active', true)
            ->get();

        return view('agency.products.kultur-turlari.create', compact('categories', 'cities', 'marketplaces'));
    }

    public function store(Request $request)
    {
        $request->validate([
            'name' => 'required|string|max:255',
            'description' => 'required|string',
            'short_description' => 'nullable|string|max:500',
            'tour_type' => 'required|in:domestic,international',
            'departure_city_id' => 'required|exists:cities,id',
            'arrival_city_id' => 'required|exists:cities,id',
            'days' => 'required|integer|min:1',
            'nights' => 'nullable|integer|min:0',
            'min_participants' => 'required|integer|min:1',
            'max_participants' => 'nullable|integer|min:1',
            'categories' => 'nullable|array',
            'categories.*' => 'exists:product_categories,id',
            'marketplaces' => 'required|array|min:1',
            'marketplaces.*' => 'exists:marketplaces,id',
        ]);

        DB::beginTransaction();
        try {
            $data = $request->all();
            $data['agency_id'] = Auth::user()->currentAgencyId();
            $data['slug'] = Str::slug($request->name);

            // Benzersiz kod oluştur
            $lastTour = Tour::where('agency_id', auth()->user()->agency_id)->latest()->first();

            if (isset($lastTour))
                $data['code'] = (int)$lastTour->code + 1;
            else
                $data['code'] = 1000;

            // Süre bilgilerini ayarla (Kültür turları için gün bazında)
            $data['duration'] = $request->days;
            if (!$request->filled('nights')) {
                $data['nights'] = max(0, $request->days - 1);
            }

            // Get product type for "kultur-turu"
            $kulturTuruType = \App\Models\Product\ProductType::where('slug', 'kultur-turu')->first();

            // Create Tour first (without product_id)
            $tour = Tour::create($data);

            // Benzersiz slug oluştur
            $uniqueSlug = \App\Models\Product\Product::generateUniqueSlug($request->name);

            // Now create Product with polymorphic relationship
            $product = \App\Models\Product\Product::create([
                'agency_id' => Auth::user()->currentAgencyId(),
                'product_type_id' => $kulturTuruType->id,
                'productable_type' => Tour::class,
                'productable_id' => $tour->id,
                'code' => $data['code'],
                'name' => $request->name,
                'slug' => $uniqueSlug,
                'description' => $request->description,
                'is_active' => true,
                'is_bookable' => true,
                'created_by' => auth()->id(),
            ]);

            // Update tour with product_id
            $tour->update(['product_id' => $product->id]);

            // Attach categories to product if provided
            if ($request->filled('categories') && is_array($request->categories)) {
                $product->categories()->attach($request->categories);
            }

            // Attach marketplaces to product if provided
            if ($request->filled('marketplaces') && is_array($request->marketplaces)) {
                $product->marketplaces()->attach($request->marketplaces);
            }

            DB::commit();

            return redirect()->route('agency.products.kultur-turlari.general', $tour)
                ->with('success', 'Tur başarıyla oluşturuldu. Şimdi detay bilgileri tamamlayabilirsiniz.');

        } catch (\Exception $e) {
            DB::rollback();
            return back()->withInput()->with('error', 'Tur oluşturulurken bir hata oluştu. ' . $e->getMessage());
        }
    }

    public function show(Tour $tour)
    {
        $this->authorize('view', $tour);

        $tour->load([
            'categories',
            'departureCity',
            'arrivalCity',
            'activeTourImages',
            'activeItineraries',
            'activePricings',
            'upcomingDates'
        ]);

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

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

        // Load transfer points and product with categories
        $tour->load(['transferPoints', 'product.categories']);

        // Get categories for "kultur-turu" product type
        $kulturTuruType = \App\Models\Product\ProductType::where('slug', 'kultur-turu')->first();
        $categories = ProductCategory::where('product_type_id', $kulturTuruType->id)
            ->where('agency_id', Auth::user()->currentAgencyId())
            ->active()
            ->orderBy('sort_order')
            ->get();

        $cities = City::orderBy('city')->get();

        // Cancellation policies from definitions
        $cancellationPolicies = Definition::byAgency(Auth::user()->currentAgencyId())
            ->whereHas('definitionType', function ($query) {
                $query->where('name', 'cancellation_policy');
            })
            ->active()
            ->orderBy('name')
            ->get();

        // Terms and conditions from definitions
        $termsConditions = Definition::byAgency(Auth::user()->currentAgencyId())
            ->whereHas('definitionType', function ($query) {
                $query->where('name', 'terms_conditions');
            })
            ->active()
            ->orderBy('name')
            ->get();

        // Inclusions templates
        $inclusionsTemplates = Definition::byAgency(Auth::user()->currentAgencyId())
            ->whereHas('definitionType', function ($query) {
                $query->where('name', 'tour_inclusions');
            })
            ->active()
            ->orderBy('name')
            ->get();

        // Exclusions templates
        $exclusionsTemplates = Definition::byAgency(Auth::user()->currentAgencyId())
            ->whereHas('definitionType', function ($query) {
                $query->where('name', 'tour_exclusions');
            })
            ->active()
            ->orderBy('name')
            ->get();

        return view('agency.products.kultur-turlari.general', compact('tour', 'categories', 'cities', 'cancellationPolicies', 'termsConditions', 'inclusionsTemplates', 'exclusionsTemplates'));
    }

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

        // Convert empty time inputs to null
        $request->merge([
            'flight_departure_time' => $request->flight_departure_time ?: null,
            'flight_arrival_time' => $request->flight_arrival_time ?: null,
        ]);

        $request->validate([
            'name' => 'required|string|max:255',
            'description' => 'required|string',
            'short_description' => 'nullable|string|max:500',
            'places_to_visit' => 'nullable|string',
            'inclusions' => 'nullable|string',
            'exclusions' => 'nullable|string',
            'terms_conditions' => 'nullable|string',
            'tour_type' => 'required|in:domestic,international',
            'departure_city_id' => 'required|exists:cities,id',
            'arrival_city_id' => 'required|exists:cities,id',
            'days' => 'required|integer|min:1',
            'nights' => 'nullable|integer|min:0',
            'min_participants' => 'required|integer|min:1',
            'max_participants' => 'nullable|integer|min:1',
            'min_age' => 'nullable|integer|min:0',
            'max_age' => 'nullable|integer|min:1',
            'difficulty_level' => 'required|in:easy,moderate,challenging,extreme',
            'difficulty_description' => 'nullable|string',
            'categories' => 'nullable|array',
            'categories.*' => 'exists:product_categories,id',
            'transportation_method' => 'nullable|in:air,road,train,ferry,other',
            'departure_airports' => 'nullable|string',
            'departure_flight_number' => 'nullable|string|max:255',
            'flight_departure_time' => 'nullable|date_format:H:i',
            'arrival_airports' => 'nullable|string',
            'arrival_flight_number' => 'nullable|string|max:255',
            'flight_arrival_time' => 'nullable|date_format:H:i',
            'has_transfer_points' => 'nullable|boolean',
            'transportation_notes' => 'nullable|string',
            'transfer_points' => 'nullable|array',
            'transfer_points.*.location_name' => 'required_with:transfer_points|string|max:255',
            'transfer_points.*.pickup_time' => 'required_with:transfer_points|date_format:H:i',
            'transfer_points.*.notes' => 'nullable|string',
            'transfer_points.*.sort_order' => 'nullable|integer',
        ]);

        DB::beginTransaction();
        try {
            $data = $request->except(['categories', 'transfer_points']);

            // Slug'ı güncelle (isim değiştiyse)
            if ($request->name !== $tour->name) {
                $data['slug'] = Str::slug($request->name);
            }

            // Süre bilgilerini ayarla (Kültür turları için gün bazında)
            $data['duration'] = $request->days;
            if (!$request->filled('nights')) {
                $data['nights'] = max(0, $request->days - 1);
            }

            $tour->update($data);

            // Update product info if exists
            if ($tour->product_id) {
                $productData = [
                    'name' => $request->name,
                    'description' => $request->description,
                ];

                // İsim değiştiyse benzersiz slug oluştur
                if ($request->name !== $tour->getOriginal('name')) {
                    $productData['slug'] = \App\Models\Product\Product::generateUniqueSlug(
                        $request->name,
                        $tour->product_id
                    );
                }

                $tour->product()->update($productData);

                // Sync categories via product if provided
                if ($request->has('categories')) {
                    $tour->product->categories()->sync($request->categories ?? []);
                }
            }

            // Handle transfer points
            if ($request->filled('transfer_points') && $request->has_transfer_points) {
                // Get existing transfer point IDs
                $existingIds = $tour->transferPoints->pluck('id')->toArray();
                $updatedIds = [];

                foreach ($request->transfer_points as $pointData) {
                    if (isset($pointData['id']) && in_array($pointData['id'], $existingIds)) {
                        // Update existing point
                        $tour->transferPoints()->where('id', $pointData['id'])->update([
                            'location_name' => $pointData['location_name'],
                            'pickup_time' => $pointData['pickup_time'],
                            'notes' => $pointData['notes'] ?? null,
                            'sort_order' => $pointData['sort_order'] ?? 0,
                        ]);
                        $updatedIds[] = $pointData['id'];
                    } else {
                        // Create new point
                        $newPoint = $tour->transferPoints()->create([
                            'location_name' => $pointData['location_name'],
                            'pickup_time' => $pointData['pickup_time'],
                            'notes' => $pointData['notes'] ?? null,
                            'sort_order' => $pointData['sort_order'] ?? 0,
                        ]);
                        $updatedIds[] = $newPoint->id;
                    }
                }

                // Delete removed points
                $tour->transferPoints()->whereNotIn('id', $updatedIds)->delete();
            } elseif (!$request->has_transfer_points) {
                // Delete all transfer points if checkbox is unchecked
                $tour->transferPoints()->delete();
            }

            DB::commit();

            return back()->with('success', 'Tur bilgileri başarıyla güncellendi.');

        } catch (\Exception $e) {
            DB::rollback();
            return back()->withInput()->with('error', 'Güncelleme sırasında bir hata oluştu.');
        }
    }

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

        $marketplaces = auth()->user()->agency->marketplaces()->where('is_active', true)->get();
        return view('agency.products.kultur-turlari.settings', compact('tour', 'marketplaces'));
    }

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

        $request->validate([
            'has_guide' => 'boolean',
            'child_friendly' => 'boolean',
            'infant_allowed' => 'boolean',
            'instant_booking' => 'boolean',
            'refundable' => 'boolean',
            'is_featured' => 'boolean',
            'is_bestseller' => 'boolean',
            'booking_deadline_hours' => 'required|integer|min:1',
            'cancellation_deadline_hours' => 'required|integer|min:1',
            'cancellation_policy' => 'nullable|string',
            'languages' => 'nullable|array',
            'requirements' => 'nullable|array',
        ]);

        $tour->update($request->all());

        if ($tour->product) {
            $tour->product->marketplaces()->sync($request->input('marketplaces', []));
        }

        if ($request->ajax() || $request->wantsJson()) {
            return response()->json([
                'success' => true,
                'message' => 'Tur ayarları başarıyla güncellendi.'
            ]);
        }

        return back()->with('success', 'Tur ayarları başarıyla güncellendi.');
    }

    public function edit(Tour $tour)
    {
        return redirect()->route('agency.products.kultur-turlari.general', $tour);
    }

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

        if ($tour->tourDates()->where('status', 'in_progress')->exists()) {
            return back()->with('error', 'Devam eden turları silemezsiniz.');
        }

        DB::beginTransaction();
        try {
            // Delete related data
            $tour->categories()->detach();
            $tour->tourImages()->delete();
            $tour->itineraries()->delete();
            $tour->pricings()->delete();
            $tour->tourDates()->delete();

            $tour->delete();

            DB::commit();

            return redirect()->route('agency.products.kultur-turlari.index')
                ->with('success', 'Tur başarıyla silindi.');

        } catch (\Exception $e) {
            DB::rollback();
            return back()->with('error', 'Tur silinirken bir hata oluştu.');
        }
    }

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

        $tour->update(['is_active' => !$tour->is_active]);

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

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

        $tour->update([
            'is_public' => !$tour->is_public,
            'published_at' => $tour->is_public ? null : now()
        ]);

        return response()->json([
            'success' => true,
            'is_public' => $tour->is_public,
            'message' => $tour->is_public ? 'Tur yayınlandı.' : 'Tur yayından kaldırıldı.'
        ]);
    }

    public function duplicate(Tour $tour)
    {
        $this->authorize('view', $tour);

        DB::beginTransaction();
        try {
            $newTour = $tour->replicate([
                'code', 'slug', 'view_count', 'booking_count',
                'rating_average', 'rating_count', 'published_at'
            ]);

            $newTour->name = $tour->name . ' - Kopya';
            $newTour->slug = Str::slug($newTour->name);
            $newTour->is_public = false;
            $newTour->published_at = null;

            // Generate unique code
            $lastTour = Tour::where('agency_id', auth()->user()->currentAgencyId())->latest()->first();

            if (isset($lastTour))
                $newTour->code = (int)$lastTour->code + 1;
            else
                $newTour->code = 1000;

            $newTour->save();

            // Copy relationships
            $newTour->categories()->attach($tour->categories->pluck('id'));

            DB::commit();

            return redirect()->route('agency.products.kultur-turlari.general', $newTour)
                ->with('success', 'Tur başarıyla kopyalandı.');

        } catch (\Exception $e) {
            DB::rollback();
            return back()->with('error', 'Tur kopyalanırken bir hata oluştu.');
        }
    }

    public function bulkDelete(Request $request)
    {
        $request->validate([
            'tours' => 'required|array',
            'tours.*' => 'exists:tours,id'
        ]);

        $tours = Tour::byAgency(Auth::user()->currentAgencyId())
            ->whereIn('id', $request->tours)
            ->get();

        $deleted = 0;
        foreach ($tours as $tour) {
            if (!$tour->tourDates()->where('status', 'in_progress')->exists()) {
                $tour->delete();
                $deleted++;
            }
        }

        return response()->json([
            'success' => true,
            'message' => "{$deleted} tur başarıyla silindi."
        ]);
    }

    public function bulkStatus(Request $request)
    {
        $request->validate([
            'tours' => 'required|array',
            'tours.*' => 'exists:tours,id',
            'status' => 'required|in:active,inactive'
        ]);

        $isActive = $request->status === 'active';

        Tour::byAgency(Auth::user()->currentAgencyId())
            ->whereIn('id', $request->tours)
            ->update(['is_active' => $isActive]);

        $status = $isActive ? 'aktif' : 'pasif';

        return response()->json([
            'success' => true,
            'message' => "Seçilen turlar {$status} edildi."
        ]);
    }

    // Ajax Helper Methods
    public function getCategories()
    {
        $kulturTuruType = \App\Models\Product\ProductType::where('slug', 'kultur-turu')->first();
        $categories = ProductCategory::where('product_type_id', $kulturTuruType->id)
            ->where('agency_id', Auth::user()->currentAgencyId())
            ->active()
            ->orderBy('name')
            ->get(['id', 'name', 'parent_id']);

        return response()->json($categories);
    }

    public function getCities()
    {
        $cities = City::orderBy('city')->get(['id', 'city']);

        return response()->json($cities);
    }

    public function search(Request $request)
    {
        $query = $request->get('q');

        $tours = Tour::byAgency(Auth::user()->currentAgencyId())
            ->where('name', 'like', '%' . $query . '%')
            ->orWhere('code', 'like', '%' . $query . '%')
            ->limit(10)
            ->get(['id', 'name', 'code']);

        return response()->json($tours);
    }

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

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

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

        $request->validate([
            'meta_title' => 'nullable|string|max:255',
            'meta_description' => 'nullable|string|max:500',
            'meta_keywords' => 'nullable|string',
            'tags' => 'nullable|string',
        ]);

        DB::beginTransaction();
        try {
            $data = $request->only(['meta_title', 'meta_description', 'meta_keywords']);

            // Process tags
            if ($request->filled('tags')) {
                $data['tags'] = array_map('trim', explode(',', $request->tags));
            } else {
                $data['tags'] = null;
            }

            $tour->update($data);

            // Update product meta info if exists
            if ($tour->product_id) {
                // Product doesn't have meta_keywords, only meta_title and meta_description
                // So we don't update it here, tour's meta fields are separate
            }

            DB::commit();

            return redirect()->route('agency.products.kultur-turlari.seo', $tour)
                ->with('success', 'SEO bilgileri başarıyla güncellendi.');

        } catch (\Exception $e) {
            DB::rollback();
            return redirect()->back()
                ->with('error', 'SEO bilgileri güncellenirken bir hata oluştu: ' . $e->getMessage())
                ->withInput();
        }
    }
}
