<?php

namespace App\Models;

// use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use NotificationChannels\WebPush\HasPushSubscriptions;

class User extends Authenticatable
{
    /** @use HasFactory<\Database\Factories\UserFactory> */
    use HasFactory, Notifiable, HasPushSubscriptions;

    /**
     * The attributes that are mass assignable.
     *
     * @var list<string>
     */
    protected $fillable = [
        'name',
        'short_name',
        'url_slug',
        'auto_fill_customer_info',
        'email',
        'phone',
        'password',
        'role',
        'can_manage_tiktok_shop',
        'profile_photo',
        'company_name',
        'company_registration',
        'company_address',
        'company_city',
        'company_state',
        'company_postcode',
        'company_country',
        'company_phone',
        'company_email',
        'company_website',
        'company_logo',
        'use_own_payment_gateway',
        'bayarcash_portal_key',
        'bayarcash_pat',
        'bayarcash_secret_key',
        'bayarcash_environment',
        'fpx_fee_type',
        'fpx_fixed_fee',
        'fpx_percentage_fee',
        'fpx_fee_bearer',
        'duitnow_fee_type',
        'duitnow_fixed_fee',
        'duitnow_percentage_fee',
        'duitnow_fee_bearer',
        'google_sheet_id',
        'google_access_token',
        'google_refresh_token',
        'google_token_expires_at',
        'google_sheets_sync_enabled',
        'google_sheets_last_sync',
        'google_email',
    ];

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var list<string>
     */
    protected $hidden = [
        'password',
        'remember_token',
        'google_access_token',
        'google_refresh_token',
    ];

    /**
     * Get the attributes that should be cast.
     *
     * @return array<string, string>
     */
    protected function casts(): array
    {
        return [
            'email_verified_at' => 'datetime',
            'password' => 'hashed',
            'use_own_payment_gateway' => 'boolean',
            'auto_fill_customer_info' => 'boolean',
            'google_sheets_sync_enabled' => 'boolean',
            'google_token_expires_at' => 'datetime',
            'google_sheets_last_sync' => 'datetime',
        ];
    }

    /**
     * Boot the model
     */
    protected static function boot()
    {
        parent::boot();

        static::creating(function ($user) {
            // Auto-generate url_slug if not provided
            if (empty($user->url_slug)) {
                $user->url_slug = self::generateUniqueUrlSlug($user->name, $user->short_name);
            }
        });

        static::updating(function ($user) {
            // If name changed and url_slug wasn't manually changed, regenerate it
            if ($user->isDirty('name') && !$user->isDirty('url_slug')) {
                $user->url_slug = self::generateUniqueUrlSlug($user->name, $user->short_name, $user->id);
            }
        });
    }

    /**
     * Generate a unique URL slug
     */
    public static function generateUniqueUrlSlug(string $name, ?string $shortName = null, ?int $excludeId = null): string
    {
        // Generate base slug from name (lowercase)
        $baseSlug = \Illuminate\Support\Str::slug($name);
        $baseSlug = strtolower($baseSlug);

        $slug = $baseSlug;
        $counter = 2;

        // Check uniqueness
        while (true) {
            $query = self::where('url_slug', $slug);

            if ($excludeId) {
                $query->where('id', '!=', $excludeId);
            }

            if (!$query->exists()) {
                break;
            }

            // Conflict found, try with short_name first
            if ($shortName && $counter === 2) {
                $slug = $baseSlug . '-' . strtolower($shortName);
            } else {
                // Use incremental number
                $slug = $baseSlug . '-' . $counter;
                $counter++;
            }
        }

        return $slug;
    }

    /**
     * Get the Poslaju settings for the user.
     */
    public function poslajuSetting()
    {
        return $this->hasOne(PoslajuSetting::class);
    }

    /**
     * Get the stores assigned to this user (for sellers).
     */
    public function stores()
    {
        return $this->belongsToMany(Store::class, 'store_user')
                    ->withTimestamps();
    }

    /**
     * Get the TikTok Shops assigned to this user (for managers).
     */
    public function tiktokShops()
    {
        return $this->belongsToMany(TikTokShop::class, 'tiktok_shop_user', 'user_id', 'tiktok_shop_id')
                    ->withTimestamps();
    }

    /**
     * Get sales pages created by this user.
     */
    public function salesPages()
    {
        return $this->hasMany(SalesPage::class, 'user_id');
    }

    /**
     * Get custom domains owned by this seller.
     */
    public function customDomains()
    {
        return $this->hasMany(SellerDomain::class, 'user_id');
    }

    /**
     * Get the primary custom domain for this seller.
     */
    public function primaryDomain()
    {
        return $this->hasOne(SellerDomain::class, 'user_id')->where('is_primary', true);
    }

    /**
     * Get orders created by this user (manual/checkout orders).
     */
    public function createdOrders()
    {
        return $this->hasMany(Order::class, 'created_by');
    }

    /**
     * Check if the user is an admin.
     */
    public function isAdmin(): bool
    {
        return $this->role === 'admin';
    }

    /**
     * Check if the user is a seller.
     */
    public function isSeller(): bool
    {
        return $this->role === 'seller';
    }

    /**
     * Check if the user is a manager.
     */
    public function isManager(): bool
    {
        return $this->role === 'manager';
    }

    /**
     * Get sellers managed by this manager.
     */
    public function managedSellers()
    {
        return $this->belongsToMany(User::class, 'manager_seller', 'manager_id', 'seller_id')
                    ->withTimestamps();
    }

    /**
     * Get managers assigned to this seller.
     */
    public function managers()
    {
        return $this->belongsToMany(User::class, 'manager_seller', 'seller_id', 'manager_id')
                    ->withTimestamps();
    }

    /**
     * Get products enabled for this user (for checkout).
     */
    public function enabledProducts()
    {
        return $this->belongsToMany(Product::class, 'user_product')
                    ->withPivot('is_enabled')
                    ->wherePivot('is_enabled', true)
                    ->withTimestamps();
    }

    /**
     * Get all products relationship (including disabled).
     */
    public function products()
    {
        return $this->belongsToMany(Product::class, 'user_product')
                    ->withPivot('is_enabled')
                    ->withTimestamps();
    }

    /**
     * Get the store IDs assigned to this user.
     * For admins, returns all store IDs.
     * For sellers, returns only assigned stores.
     * For managers, returns stores from all managed sellers.
     */
    public function getStoreIds(): array
    {
        if ($this->isAdmin()) {
            return Store::pluck('id')->toArray();
        }

        if ($this->isManager()) {
            // Get all store IDs from managed sellers
            $storeIds = [];
            foreach ($this->managedSellers as $seller) {
                $storeIds = array_merge($storeIds, $seller->stores()->pluck('stores.id')->toArray());
            }
            return array_unique($storeIds);
        }

        return $this->stores()->pluck('stores.id')->toArray();
    }

    /**
     * Get the TikTok Shop IDs assigned to this user.
     * For admins, returns all TikTok Shop IDs.
     * For managers, returns only assigned TikTok Shops.
     */
    public function getTikTokShopIds(): array
    {
        if ($this->isAdmin()) {
            return TikTokShop::pluck('id')->toArray();
        }

        return $this->tiktokShops()->pluck('tiktok_shops.id')->toArray();
    }

    /**
     * Get all managed seller IDs (for managers).
     */
    public function getManagedSellerIds(): array
    {
        if (!$this->isManager()) {
            return [];
        }

        return $this->managedSellers()->pluck('users.id')->toArray();
    }

    /**
     * Get the URL slug for this seller.
     * Returns the url_slug field or generates one if missing.
     * Example: "nadia", "nadia-m0004", "siti-2"
     */
    public function getUrlSlug(): string
    {
        // Return the url_slug field if it exists
        if (!empty($this->url_slug)) {
            return $this->url_slug;
        }

        // Fallback: generate on-the-fly (for legacy data)
        return strtolower(\Illuminate\Support\Str::slug($this->name));
    }
}
