<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use App\Models\Translation; // Using the generic Translation model

class Location extends Model
{
    use HasFactory;

    protected $table = 'locations';

    protected $fillable = [
        'title_id',
        'category',
        'category_id',
        'category_fa',
        'title',
        'ad_package',
        'ad_expiry',
        'display_until',
        'description',
        'Slogan',
        'lat',
        'lng',
        'url',
        'phone',
        'open_hours',
        'closing_hours',
        'country_id',
        'province_id',
        'county_id',
        'district_id',
        'city_id',
        'village_id',
        'zone_id',
        'address',
        'tags',
        'images',
        'amenities',
        'star_rating',
        'emoji',
        'is_active',
        'user_id',
        'package_type',
        'package_expires_at',
    ];

    /**
     * Get the translations for the location.
     */
    public function translations()
    {
        return $this->morphMany(Translation::class, 'translatable');
    }

    protected $casts = [
        'lat' => 'decimal:7',
        'lng' => 'decimal:7',
        'ad_expiry' => 'date',
        'display_until' => 'date',
        'star_rating' => 'integer',
        'is_active' => 'boolean',
        'images' => 'array',
        'amenities' => 'array',
        'package_expires_at' => 'datetime',
    ];

    /**
     * Get images as array, handling both array and JSON string formats
     * Also filters out empty or invalid entries
     *
     * @return array
     */
    public function getImagesArrayAttribute()
    {
        $images = [];

        if (is_array($this->images)) {
            $images = $this->images;
        } elseif (is_string($this->images)) {
            $decoded = json_decode($this->images, true);
            $images = is_array($decoded) ? $decoded : [];
        }

        // Filter out empty, null, or non-string values
        return array_filter($images, function($image) {
            return !empty($image) && is_string($image) && trim($image) !== '';
        });
    }

    /**
     * Get amenities as array, handling both array and JSON string formats
     *
     * @return array
     */
    public function getAmenitiesArrayAttribute()
    {
        if (is_array($this->amenities)) {
            return $this->amenities;
        } elseif (is_string($this->amenities)) {
            $decoded = json_decode($this->amenities, true);
            return is_array($decoded) ? $decoded : [];
        }
        return [];
    }

    /**
     * Set images attribute, ensuring it's always stored as a clean array
     *
     * @param mixed $value
     */
    public function setImagesAttribute($value)
    {
        if (is_array($value)) {
            // Filter out empty or invalid entries
            $cleanImages = array_filter($value, function($image) {
                return !empty($image) && is_string($image) && trim($image) !== '';
            });
            $this->attributes['images'] = json_encode(array_values($cleanImages));
        } elseif (is_string($value)) {
            $decoded = json_decode($value, true);
            if (is_array($decoded)) {
                $this->setImagesAttribute($decoded);
            } else {
                $this->attributes['images'] = json_encode([]);
            }
        } else {
            $this->attributes['images'] = json_encode([]);
        }
    }

    /**
     * Get the URL for the location with category path
     *
     * @return string
     */
    public function getUrl()
    {
        if ($this->category_id) {
            $categoryParts = [];
            $currentCategory = null;

            // Try to use the relationship
            if (isset($this->categoryRelation) && is_object($this->categoryRelation)) {
                $currentCategory = $this->categoryRelation;
            } else {
                // Try to load directly
                $currentCategory = Category::find($this->category_id);
            }

            if ($currentCategory) {
                // Start with the current category
                if (isset($currentCategory->category_key) && ! empty($currentCategory->category_key)) {
                    $categoryParts[] = $currentCategory->category_key;
                }

                // Load parent categories recursively
                while ($currentCategory && isset($currentCategory->parent_id) && $currentCategory->parent_id > 0) {
                    $parent = Category::find($currentCategory->parent_id);
                    if ($parent && isset($parent->category_key) && ! empty($parent->category_key)) {
                        // Insert at the beginning (parent first, then child)
                        array_unshift($categoryParts, $parent->category_key);
                        $currentCategory = $parent;
                    } else {
                        break;
                    }
                }

                if (! empty($categoryParts)) {
                    return url(implode('/', $categoryParts).'/'.$this->title_id);
                }
            }
        }

        // Fallback to old URL format
        return url('/l/'.$this->title_id);
    }

    /**
     * Generate a URL-friendly slug from a string
     *
     * @param  string  $text
     * @return string
     */
    protected function generateSlug($text)
    {
        // Convert to lowercase
        $text = mb_strtolower($text, 'UTF-8');

        // Replace spaces with underscores
        $text = str_replace(' ', '_', $text);

        // Remove any character that's not a letter, number, hyphen or underscore
        $text = preg_replace('/[^\p{L}\p{N}_\-]/u', '', $text);

        // Remove multiple hyphens or underscores
        $text = preg_replace('/-+/', '-', $text);
        $text = preg_replace('/_+/', '_', $text);

        // Trim hyphens and underscores from the beginning and end
        return trim($text, '-_');
    }

    /**
     * دریافت نام ترجمه‌شده مکان بر اساس زبان فعال
     *
     * @param string $languageCode کد زبان (fa, en, ...)
     * @return string نام ترجمه‌شده
     */
    public function getTranslatedName($languageCode = 'fa')
    {
        // استفاده از کش برای بهبود عملکرد
        $cacheKey = "location_{$this->id}_name_{$languageCode}";

        return cache()->remember($cacheKey, now()->addHours(24), function () use ($languageCode) {
            // اولویت اول: ترجمه در جدول translations
            $translation = $this->translations()
                ->where('language_code', $languageCode)
                ->first();

            if ($translation && !empty($translation->name)) {
                return $translation->name;
            }

            // اولویت دوم: نام اصلی
            return $this->title;
        });
    }

    public function getTranslatedAddress($lang = null)
    {
        $lang = $lang ?: app()->getLocale();
        $translation = $this->translations()->where('language_code', $lang)->first();
        if ($translation && !empty($translation->address)) {
            return $translation->address;
        }
        return $this->address;
    }

    public function getStructuredAddress($lang = null)
    {
        $lang = $lang ?: app()->getLocale();
        $parts = [];
        // منطقه
        if ($this->zone) {
            $parts[] = $lang === 'en' ? $this->zone->name_en : $this->zone->name;
        }
        // روستا
        if ($this->village) {
            $parts[] = $lang === 'en' ? $this->village->name_en : $this->village->name;
        }
        // شهر
        if ($this->city) {
            $parts[] = $lang === 'en' ? $this->city->name_en : $this->city->name;
        }
        // بخش
        if ($this->district) {
            $parts[] = $lang === 'en' ? $this->district->name_en : $this->district->name;
        }
        // شهرستان
        if ($this->county) {
            $parts[] = $lang === 'en' ? $this->county->name_en : $this->county->name;
        }
        // استان
        if ($this->province) {
            $parts[] = $lang === 'en' ? $this->province->name_en : $this->province->name;
        }
        // کشور
        if ($this->country) {
            $parts[] = $lang === 'en' ? $this->country->name_en : $this->country->name;
        }
        $separator = $lang === 'en' ? ', ' : '، ';
        return implode($separator, array_filter($parts));
    }

    /**
     * دریافت نام ترجمه‌شده دسته‌بندی مکان بر اساس زبان فعال
     *
     * @param string $languageCode کد زبان (fa, en, ...)
     * @return string نام ترجمه‌شده دسته‌بندی
     */
    public function getTranslatedCategoryName($languageCode = null)
    {
        if (!$languageCode) {
            $languageCode = app()->getLocale();
        }

        if (!$this->categoryRelation) {
            return '';
        }

        return $this->categoryRelation->getTranslatedName($languageCode);
    }

    // Relationships
    public function categoryRelation()
    {
        return $this->belongsTo(Category::class, 'category_id');
    }

    public function country()
    {
        return $this->belongsTo(Country::class, 'country_id');
    }

    public function province()
    {
        return $this->belongsTo(Province::class, 'province_id');
    }

    public function county()
    {
        return $this->belongsTo(County::class, 'county_id');
    }

    public function district()
    {
        return $this->belongsTo(District::class, 'district_id');
    }

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

    public function village()
    {
        return $this->belongsTo(Village::class, 'village_id');
    }

    public function zone()
    {
        return $this->belongsTo(Zone::class, 'zone_id');
    }

    public function locationAmenities()
    {
        return $this->hasMany(LocationAmenity::class);
    }

    public function ratings()
    {
        return $this->hasMany(Rating::class, 'title_id', 'title_id');
    }

    public function contents()
    {
        return $this->hasMany(LocationContent::class);
    }

    public function seo()
    {
        return $this->hasOne(LocationSeo::class);
    }

    /**
     * دریافت بازدیدهای مکان
     */
    public function visits()
    {
        return $this->hasMany(Visit::class);
    }

    /**
     * دریافت کاربر ثبت کننده مکان
     */
    public function user()
    {
        return $this->belongsTo(User::class, 'user_id');
    }
}
