<?php

namespace App\Models\Tour;

use App\Models\Agency\Agency;
use App\Models\Definition\City;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Str;

class Tour extends Model
{
    use HasFactory, SoftDeletes;

    protected $table = 'cultural_tours';

    protected $fillable = [
        'product_id',
        'agency_id',
        'code',
        'name',
        'slug',
        'description',
        'short_description',
        'places_to_visit',
        'inclusions',
        'exclusions',
        'cancellation_policy',
        'terms_conditions',
        'video_url',
        'documents',
        'tour_type',
        'pricing_type',
        'transportation_type',
        'transportation_method',
        'departure_airports',
        'departure_flight_number',
        'flight_departure_time',
        'arrival_airports',
        'arrival_flight_number',
        'flight_arrival_time',
        'has_transfer_points',
        'transportation_notes',
        'has_guide',
        'languages',
        'duration',
        'days',
        'nights',
        'departure_time',
        'return_time',
        'departure_city_id',
        'arrival_city_id',
        'destinations',
        'distance_km',
        'departure_latitude',
        'departure_longitude',
        'arrival_latitude',
        'arrival_longitude',
        'min_participants',
        'max_participants',
        'min_age',
        'max_age',
        'child_friendly',
        'infant_allowed',
        'difficulty_level',
        'difficulty_description',
        'fitness_level',
        'requirements',
        'instant_booking',
        'booking_deadline_hours',
        'cancellation_deadline_hours',
        'refundable',
        'meta_title',
        'meta_description',
        'meta_keywords',
        'tags',
        'is_featured',
        'is_bestseller',
        'is_new',
        'priority',
        'is_active',
        'is_public',
        'is_bookable',
        'published_at',
        'expires_at',
        'view_count',
        'booking_count',
        'wishlist_count',
        'rating_average',
        'rating_count',
        'external_ids',
        'api_data',
        'created_by',
        'updated_by',
    ];

    protected function casts(): array
    {
        return [
            'documents' => 'array',
            'languages' => 'array',
            'destinations' => 'array',
            'requirements' => 'array',
            'tags' => 'array',
            'external_ids' => 'array',
            'api_data' => 'array',
            'has_guide' => 'boolean',
            'has_transfer_points' => 'boolean',
            'child_friendly' => 'boolean',
            'infant_allowed' => 'boolean',
            'instant_booking' => 'boolean',
            'refundable' => 'boolean',
            'is_featured' => 'boolean',
            'is_bestseller' => 'boolean',
            'is_new' => 'boolean',
            'is_active' => 'boolean',
            'is_public' => 'boolean',
            'is_bookable' => 'boolean',
            'published_at' => 'datetime',
            'expires_at' => 'datetime',
            'departure_time' => 'datetime',
            'return_time' => 'datetime',
            'distance_km' => 'decimal:2',
            'departure_latitude' => 'decimal:8',
            'departure_longitude' => 'decimal:8',
            'arrival_latitude' => 'decimal:8',
            'arrival_longitude' => 'decimal:8',
            'rating_average' => 'decimal:2',
        ];
    }

    // Basic Relationships
    public function agency()
    {
        return $this->belongsTo(Agency::class);
    }

    public function product()
    {
        return $this->belongsTo(\App\Models\Product\Product::class, 'product_id');
    }

    public function departureCity()
    {
        return $this->belongsTo(City::class, 'departure_city_id');
    }

    public function arrivalCity()
    {
        return $this->belongsTo(City::class, 'arrival_city_id');
    }

    public function creator()
    {
        return $this->belongsTo(User::class, 'created_by');
    }

    public function updater()
    {
        return $this->belongsTo(User::class, 'updated_by');
    }

    // Tour Categories relationship (Many-to-Many through product_category via Product)
    public function categories()
    {
        // Eğer product_id varsa, product üzerinden kategorileri al
        if ($this->product_id) {
            return $this->belongsToMany(
                \App\Models\Product\ProductCategory::class,
                'product_category',
                'product_id',
                'category_id'
            )->wherePivot('product_id', $this->product_id);
        }

        // Yoksa boş collection döndür
        return $this->belongsToMany(
            \App\Models\Product\ProductCategory::class,
            'product_category',
            'product_id',
            'category_id'
        )->whereRaw('1 = 0'); // Always false, returns empty
    }

    // Tour Images relationships
    public function tourImages()
    {
        return $this->hasMany(TourImage::class, 'cultural_tour_id')->ordered();
    }

    public function activeTourImages()
    {
        return $this->hasMany(TourImage::class, 'cultural_tour_id')->active()->approved()->ordered();
    }

    public function coverImage()
    {
        return $this->hasOne(TourImage::class, 'cultural_tour_id')->cover()->active();
    }

    public function featuredImages()
    {
        return $this->hasMany(TourImage::class, 'cultural_tour_id')->featured()->active()->ordered();
    }

    public function galleryImages()
    {
        return $this->hasMany(TourImage::class, 'cultural_tour_id')->forGallery()->active()->ordered();
    }

    public function sliderImages()
    {
        return $this->hasMany(TourImage::class, 'cultural_tour_id')->forSlider()->active()->ordered();
    }

    public function thumbnailImages()
    {
        return $this->hasMany(TourImage::class, 'cultural_tour_id')->forThumbnails()->active()->ordered();
    }

    public function itineraryImages()
    {
        return $this->hasMany(TourImage::class, 'cultural_tour_id')->bySection('itinerary')->active()->ordered();
    }

    // Tour Itineraries relationship
    public function itineraries()
    {
        return $this->hasMany(TourItinerary::class, 'cultural_tour_id')->ordered();
    }

    public function activeItineraries()
    {
        return $this->hasMany(TourItinerary::class, 'cultural_tour_id')->active()->ordered();
    }

    // Tour Transfer Points relationship
    public function transferPoints()
    {
        return $this->hasMany(TourTransferPoint::class, 'cultural_tour_id')->orderBy('sort_order');
    }

    public function activeTransferPoints()
    {
        return $this->hasMany(TourTransferPoint::class, 'cultural_tour_id')->active()->orderBy('sort_order');
    }

    public function departurePoints()
    {
        return $this->hasMany(TourTransferPoint::class, 'cultural_tour_id')->departurePoints();
    }

    public function transferStops()
    {
        return $this->hasMany(TourTransferPoint::class, 'cultural_tour_id')->transferPoints();
    }

    public function getItinerariesByDay($dayNumber)
    {
        return $this->itineraries()->byDay($dayNumber)->get();
    }

    public function getItineraryDays()
    {
        return $this->itineraries()->select('day_number')->distinct()->orderBy('day_number')->pluck('day_number');
    }

    // Tour Pricings relationship
    public function pricings()
    {
        return $this->hasMany(TourPricing::class, 'cultural_tour_id')->ordered();
    }

    public function activePricings()
    {
        return $this->hasMany(TourPricing::class, 'cultural_tour_id')->active()->ordered();
    }

    public function defaultPricing()
    {
        return $this->hasOne(TourPricing::class, 'cultural_tour_id')->default()->active();
    }

    public function getPricingForDate($date)
    {
        // Önce o tarihte aktif bir TourDate varsa onun fiyatını kullan
        $tourDate = $this->tourDates()
            ->where('start_date', '<=', $date)
            ->where('end_date', '>=', $date)
            ->where('is_active', true)
            ->first();

        if ($tourDate) {
            return $tourDate; // TourDate kendi fiyatlarını tutuyor
        }

        // Yoksa default pricing'i kullan
        return $this->defaultPricing;
    }

    public function tourDates()
    {
        return $this->hasMany(TourDate::class, 'cultural_tour_id')->orderBy('start_date');
    }

    public function upcomingDates()
    {
        return $this->hasMany(TourDate::class, 'cultural_tour_id')->upcoming()->available();
    }

    public function getLowestPrice()
    {
        return $this->activePricings()->min('adult_price') ?: 0;
    }

    public function getHighestPrice()
    {
        return $this->activePricings()->max('adult_price') ?: 0;
    }

    // Scopes
    public function scopeActive($query)
    {
        return $query->where('is_active', true);
    }

    public function scopePublic($query)
    {
        return $query->where('is_public', true);
    }

    public function scopeBookable($query)
    {
        return $query->where('is_bookable', true);
    }

    public function scopeFeatured($query)
    {
        return $query->where('is_featured', true);
    }

    public function scopeBestseller($query)
    {
        return $query->where('is_bestseller', true);
    }

    public function scopeNew($query)
    {
        return $query->where('is_new', true);
    }

    public function scopeByAgency($query, $agencyId)
    {
        return $query->where('agency_id', $agencyId);
    }

    public function scopeByTourType($query, $type)
    {
        return $query->where('tour_type', $type);
    }

    public function scopeByDepartureCity($query, $cityId)
    {
        return $query->where('departure_city_id', $cityId);
    }

    public function scopeByDuration($query, $min, $max)
    {
        return $query->whereBetween('duration', [$min, $max]);
    }

    // Helper Methods
    public function isExpired()
    {
        return $this->expires_at && $this->expires_at->isPast();
    }

    public function isPublished()
    {
        return $this->published_at && $this->published_at->isPast();
    }

    public function isAvailable()
    {
        return $this->is_active && $this->is_public && $this->is_bookable && !$this->isExpired();
    }

    public function getFormattedPriceAttribute()
    {
        $defaultPricing = $this->defaultPricing;
        if ($defaultPricing) {
            return number_format($defaultPricing->adult_price, 2) . ' ' . $defaultPricing->currency;
        }
        return 'Fiyat Belirtilmemiş';
    }

    public function getDiscountedPriceAttribute()
    {
        // Bu method daha sonra promosyon sistemi eklendiğinde genişletilebilir
        $defaultPricing = $this->defaultPricing;
        return $defaultPricing ? $defaultPricing->adult_price : 0;
    }

    public function getCurrencyAttribute()
    {
        $defaultPricing = $this->defaultPricing;
        return $defaultPricing ? $defaultPricing->currency : 'TRY';
    }

    // Tour Image helper methods
    public function getCoverImageUrlAttribute()
    {
        return $this->coverImage?->image_url;
    }

    public function getThumbnailUrlAttribute()
    {
        return $this->coverImage?->thumbnail_url ?: $this->featuredImages->first()?->thumbnail_url;
    }

    public function getGalleryImageUrlsAttribute()
    {
        return $this->galleryImages->pluck('image_url')->toArray();
    }

    public function hasImages()
    {
        return $this->activeTourImages()->count() > 0;
    }

    public function getImageCount()
    {
        return $this->activeTourImages()->count();
    }

    public function addImageFromDisk($diskItemId, array $attributes = [])
    {
        $defaultAttributes = [
            'disk_item_id' => $diskItemId,
            'image_type' => 'gallery',
            'sort_order' => $this->tourImages()->count(),
            'is_active' => true,
            'is_approved' => true,
            'approved_at' => now(),
            'approved_by' => auth()->id(),
        ];

        return $this->tourImages()->create(array_merge($defaultAttributes, $attributes));
    }

    // Backward compatibility alias
    public function addImageFromGallery($diskItemId, array $attributes = [])
    {
        return $this->addImageFromDisk($diskItemId, $attributes);
    }

    public function setCoverImage($diskItemId)
    {
        return $this->addImageFromDisk($diskItemId, [
            'image_type' => 'cover',
            'is_cover' => true,
            'show_in_gallery' => true,
            'show_in_slider' => true,
        ]);
    }

    public function addFeaturedImage($diskItemId)
    {
        return $this->addImageFromDisk($diskItemId, [
            'image_type' => 'featured',
            'is_featured' => true,
            'show_in_gallery' => true,
            'show_in_slider' => true,
        ]);
    }

    // Tour Status Methods
    public function getTourTypeDisplayNameAttribute()
    {
        $types = [
            'domestic' => 'İç Turizm',
            'international' => 'Dış Turizm',
        ];

        return $types[$this->tour_type] ?? ucfirst($this->tour_type);
    }

    public function getAccommodationTypeDisplayNameAttribute()
    {
        // Kültür turları her zaman konaklamalıdır
        return 'Konaklamalı';
    }

    public function getDifficultyLevelDisplayNameAttribute()
    {
        $levels = [
            'easy' => 'Kolay',
            'moderate' => 'Orta',
            'challenging' => 'Zor',
            'extreme' => 'Çok Zor',
        ];

        return $levels[$this->difficulty_level] ?? ucfirst($this->difficulty_level);
    }

    protected static function boot()
    {
        parent::boot();

        static::creating(function ($tour) {
            if (empty($tour->slug)) {
                $tour->slug = Str::slug($tour->name);
            }

            if (empty($tour->code)) {
                $tour->code = 'TOUR' . sprintf('%06d', static::count() + 1);
            }

            if (auth()->check()) {
                $tour->created_by = auth()->id();
            }
        });

        static::updating(function ($tour) {
            if (auth()->check()) {
                $tour->updated_by = auth()->id();
            }
        });
    }
}
