<?php
/**
 * Class represents records from table files
 * "path" field may contain numeric id - from the uploads table
 * {autogenerated}
 * @property int $product_option_id PK
 * @property int $product_id FK product
 * @property string $name
 * @property string|null $desc
 * @property string $title
 * @property string|null $description
 * @property string $type
 * @property int|null $size
 * @property string|null $default
 * @property string|null $options
 * @property int|null $is_required
 * @property int $sort_order
 * {/autogenerated}
 */
class ProductOption extends Am_Record
{
    protected $_options;

    public function getDecodedOptions()
    {
        if ($this->_options === null)
            if (!$this->options)
                $this->_options = [];
            else
                $this->_options = json_decode($this->options, true);
        return $this->_options;
    }

    public function setOptions($jsonOptions)
    {
        $this->options = $jsonOptions;
        return $this;
    }

    /**
     * return prices for selected billing plan
     */
    public function getPrices($billing_plan_id, $key)
    {
        $o = $this->getDecodedOptions();
        if (!empty($o['prices'][$key][$billing_plan_id]))
            return $o['prices'][$key][$billing_plan_id];
        else
            return [0,0];
    }

    /**
     * get key-value options for select
     */
    function getSelectOptions()
    {
        $o = $this->getDecodedOptions();
        if (empty($o['options'])) return [];
        $ret = [];
        foreach ($o['options'] as $v)
            $ret[$v[0]] = $v[1];
        return $ret;
    }
    /**
     * get key-value options for select
     */
    function getSelectOptionsWithPrice(BillingPlan $plan, $isHtml = true)
    {
        $o = $this->getDecodedOptions();
        if (empty($o['options'])) return [];
        $ret = [];
        $ob = new stdclass;
        $ob->first_period = $plan->first_period;
        $ob->second_period = $plan->second_period;
        $ob->rebill_times = $plan->rebill_times;
        $ob->currency = $plan->currency;
        foreach ($o['options'] as $v)
        {
            $prices = $this->getPrices($plan->pk(), $v[0]);
            $priceLabel = '';
            if (!empty($prices[0]) || !empty($prices[1]))
            {
                $ob->first_price = empty($prices[0]) ? 0 : abs(floatval($prices[0]));
                $ob->second_price = empty($prices[1]) ? 0 : abs(floatval($prices[1]));
                $t = new Am_TermsText($ob);
                $sign = $prices[0] > 0 ? '+' : '&minus;';
                $format = $isHtml ? ' <span class="am-option-price">%s</span>' : ' (%s)';
                $priceLabel = sprintf($format, $sign . $t->getStringForOption());
            }
            $ret[$v[0]] = $v[1] . $priceLabel;
        }
        return $ret;
    }
    /**
     * return array of default keys of getSelectOptions()
     */
    function getDefaults()
    {
        $o = $this->getDecodedOptions();
        if (empty($o['default'])) return [];
        return array_values($o['default']);
    }
    function getDefault()
    {
        $def = $this->getDefaults();
        return current($def);
    }

    /**
     * return label(s) of values
     */
    function getOptionLabel($val)
    {
        if ($this->type == 'date' && $val) {
            return amDate($val);
        }

        if (empty($this->options) || !($labels = $this->getSelectOptions()))
        {
            return $val;
        }
        if (!is_array($val))
            return $labels[$val] ? $labels[$val] : $val;
        else {
            foreach ($val as & $x)
                $x = $labels[$x] ? $labels[$x] : $x;
        }
        return $val;
    }
}

/**
 * @extends Am_Table<ProductOption>
 * @method void deleteByProductId($value, $useObjects = true)
 * @method ProductOption[] findByProductId($value, $start = null, $count = null, $orderBy = null)
 */
class ProductOptionTable extends Am_Table
{
    protected $_key = 'product_option_id';
    protected $_table = '?_product_option';
    protected $_recordClass = 'ProductOption';

    function findBy(array $conditions = [], $start = null, $count = null, $orderBy = null)
    {
        if ($orderBy === null)
            $orderBy = 'sort_order';
        return parent::findBy($conditions, $start, $count, $orderBy);
    }
}
