<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;

class Plan extends BaseModel
{
    use HasFactory;

    protected $fillable = [
        'name',
        'number_of_user',
        'custom_plan',
        'active',
        'is_free_plan',
        'status',
        'package_price_monthly',
        'package_price_yearly',
        'price_per_user_monthly',
        'price_per_user_yearly',
        'price_per_workspace_monthly',
        'price_per_workspace_yearly',
        'module_id',
        'number_of_workspace',
        'price_key_yearly',
        'price_key',
    ];

    /**
     * The accessors to append to the model's array form.
     *
     * @var array
     */
    protected $appends = [
        'modules',
    ];

    /**
     * Get modules associated with this plan.
     *
     * @return array|\Illuminate\Database\Eloquent\Collection
     */
    public function getModulesAttribute()
    {
        if (!$this->module_id) {
            return [];
        }
        $moduleIds = explode(',', $this->module_id);
        return PermissionsModules::whereIn('id', $moduleIds)->get();
    }

    /**
     * Get all valid coupons applicable to this plan.
     *
     * @return \Illuminate\Database\Eloquent\Collection
     */
   

    /**
     * Get available discounts for this plan.
     *
     * @return array
     */
   

    /**
     * Get all users associated with this plan.
     */
    public function users()
    {
        return $this->hasMany(User::class, 'active_plan_id', 'id');
    }

    /**
     * Get all orders associated with this plan.
     */
    public function orders()
    {
        return $this->hasMany(Order::class);
    }

    /**
     * Get all subscriptions associated with this plan.
     */
    public function subscriptions()
    {
        return $this->hasMany(Subscription::class);
    }

    /**
     * Get all coupons where this plan is included.
     */
    public function coupons()
    {
        return $this->belongsToJsonMany(Coupon::class, 'included_plan', 'id');
    }

    /**
     * Get all coupons where this plan is excluded.
     */
    public function excludedFromCoupons()
    {
        return $this->belongsToJsonMany(Coupon::class, 'excluded_plan', 'id');
    }

    /**
     * Define a belongs-to-many relationship based on JSON array columns in the related model.
     * This is a custom relation that can be eager loaded.
     */
    protected function belongsToJsonMany($related, $jsonColumn, $localKey)
    {
        $instance = new $related;
        
        return new class($instance->newQuery(), $this, $jsonColumn, $localKey) {
            protected $query;
            protected $parent;
            protected $jsonColumn;
            protected $localKey;
            
            public function __construct($query, $parent, $jsonColumn, $localKey)
            {
                $this->query = $query;
                $this->parent = $parent;
                $this->jsonColumn = $jsonColumn;
                $this->localKey = $localKey;
            }
            
            public function get($columns = ['*'])
            {
                return $this->query->whereJsonContains($this->jsonColumn, $this->parent->{$this->localKey})->get($columns);
            }
            
            public function count()
            {
                return $this->query->whereJsonContains($this->jsonColumn, $this->parent->{$this->localKey})->count();
            }
            
            public function active()
            {
                return $this->query->where('is_active', 1)
                    ->whereJsonContains($this->jsonColumn, $this->parent->{$this->localKey})
                    ->get();
            }
            
            // Allows for chaining Eloquent query methods
            public function __call($method, $parameters)
            {
                $this->query->whereJsonContains($this->jsonColumn, $this->parent->{$this->localKey});
                return $this->query->$method(...$parameters);
            }
        };
    }

    /**
     * Get all coupons applicable to this plan
     */
    public function applicableCoupons()
    {
        return Coupon::applicableToPlan($this->id)->where('is_active', 1)->get();
    }

    /**
     * Check if this plan is included in a specific coupon.
     */
    public function isIncludedInCoupon($couponId)
    {
        $coupon = Coupon::find($couponId);
        return $coupon && $coupon->includesPlan($this->id);
    }

    /**
     * Get the monthly price of the plan.
     */
    public function getMonthlyPriceAttribute()
    {
        return $this->package_price_monthly ?? 0;
    }

    /**
     * Get the yearly price of the plan.
     */
    public function getYearlyPriceAttribute()
    {
        return $this->package_price_yearly ?? 0;
    }
}