<?php

namespace App\Models;

use Gloudemans\Shoppingcart\Contracts\Buyable;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;

class Addon extends Model implements Buyable
{
    protected $guarded = ['id'];

    protected $casts = [
        'product_level' => 'boolean',
        'billing_type' => 'integer',
        'price' => 'decimal:2',
    ];

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

        static ::deleting(function ($model) {
            // Detach pricing tiers
            $model->pricingTiers()->detach();
        });
    }

    public function product()
    {
        return $this->belongsTo(Product::class);
    }

    public function plan()
    {
        return $this->belongsTo(Plan::class);
    }

    public function pricingTiers()
    {
        return $this->belongsToMany(
            PricingTier::class,
            'addon_pricing_tier'
        )->withPivot(['price', 'billing_cycle_override']);
    }

    public function plans()
    {
        return $this->belongsToMany(Plan::class, 'addon_plan')->withTimestamps();
    }

    /**
     * Get the identifier of the Buyable item.
     *
     * @return int|string
     */
    public function getBuyableIdentifier($options = null)
    {
        return $this->id;
    }

    /**
     * Get the description or title of the Buyable item.
     *
     * @return string
     */
    public function getBuyableDescription($options = null)
    {
        return $this->name;
    }

    /**
     * Get the price of the Buyable item.
     *
     * @return float
     */
    public function getBuyablePrice($options = null)
    {

    }

    public function orderItems()
    {
        return $this->morphMany(OrderItem::class, 'purchasable');
    }

    public function isRecurring()
    {
        return $this->billing_type == getConstant('BILLING_SUBSCRIPTION');
    }

    public function price(): Attribute
    {
        return Attribute::make(
            get: fn ($value) => $value === null
                ? $this->pivot->price ?? null
                : $value
        );
    }

    public function billingCycle(): Attribute
    {
        return Attribute::make(
            get: fn ($value) => $value === null
                ? $this->pivot->billing_cycle_override ?? null
                : $value
        );
    }

    public function toArray()
    {
        $array = parent::toArray();

        if ($this->trial_duration_unit !== null) {
            $array['trial_duration_unit_label'] = getConstantLabel('trial_duration_unit', $this->trial_duration_unit);
        }

        if ($this->billing_cycle) {
            $array['billing_cycle_label'] = getConstantLabel('billing_cycle', $this->billing_cycle);
        }

        $array['formattedPrice'] = ch_format_price($this->price);

        return $array;
    }

    public function toJson($options = 0)
    {
        $array = $this->toArray();
        $array['formattedPrice'] = ch_format_price($this->price);
        return json_encode($array, $options);
    }
}
