<?php
namespace App\Domains\Virtual\Services;

use App\Dicts;
use App\Core\Service;
use App\Models\Virtual\Package;
use Illuminate\Validation\Rule;
use App\Exceptions\NotExistException;
use Illuminate\Support\Facades\Validator;
use App\Domains\Virtual\Services\CommonService;
use App\Domains\Virtual\Repositories\PackageRepository;

class PackageService extends Service
{
    protected $packageRepository;

    protected static $packages;

    /**
     * 构造函数
     *
     * @return void
     */
    public function __construct(PackageRepository $packageRepository)
    {
        $this->packageRepository = $packageRepository;
    }

    /**
     * 套餐列表
     *
     * @param array $conditions
     * @return mixed
     */
    public function index(array $conditions = [])
    {
        $limit = $conditions['limit'] ?? 20;

        $packages = $this->packageRepository->withConditions($conditions)
            ->applyConditions()->paginate($limit);

        $carrierOperators = app(Dicts::class)->get('carrier_operator');

        $packages->map(function ($item) use ($carrierOperators) {
            $item->cost_price = sprintf('%.02f', $item->cost_price/100);
            $item->guide_price = sprintf('%.02f', $item->guide_price/100);
            $item->carrier_operator_name = $carrierOperators[$item->carrier_operator];
            $item->status = $item->deleted_at ? 2 : $item->status;
        });

        return $packages;
    }

    /**
     * 存储套餐
     *
     * @param array $attributes
     * @param Package $parent
     * @return Package
     */
    public function store(array $attributes = [])
    {
        $attributes = array_only($attributes, array_merge(app(Package::class)->getFillable()));

        $attributes['sn'] = $attributes['sn'] ?: CommonService::generatePackageSn(
            $attributes['type'],
            $attributes['carrier_operator'],
            $attributes['flows'],
            $attributes['reset_months'],
            $attributes['service_months']
        );

        $rule = [
            'sn' => ['required', 'between:2,32', Rule::unique($this->packageRepository->getTable(), 'sn')->ignore($attributes['id'])->whereNUll('deleted_at')],
            'name' => ['required', 'between:2,32', Rule::unique($this->packageRepository->getTable(), 'name')->ignore($attributes['id'])->whereNUll('deleted_at')],
            'type' => ['required', 'in:0,2,3'],
            'carrier_operator' => ['required', 'in:0,1,2,3'],
            'cost_price' => ['numeric', 'min:0'],
            'guide_price' => ['numeric', 'min:0'],
            'flows' => ['numeric', 'min:0'],
            'voices' => ['numeric', 'min:0'],
            'messages' => ['numeric', 'min:0'],
            'has_messages' => ['in:0,1'],
            'has_lbs' => ['in:0,1'],
            'reset_months' => ['numeric', "max:{$attributes['service_months']}", 'min:0'],
            'service_months' => ['numeric', 'min:0'],
            'effect_months' => ['numeric', 'min:0'],
            'delay_months' => ['numeric', 'min:0'],
            'description' => ['max:255'],
        ];

        $message = [
            'sn.required' => '请输入套餐编号',
            'sn.between' => '套餐编号长度不合法',
            'sn.unique' => '已存在相同的套餐，请勿重复添加',
            'name.required' => '请输入套餐名称',
            'name.between' => '套餐名称长度不合法',
            'name.unique' => '套餐名称已经被其他用户所使用',
            'type.required' => '请选择套餐类型',
            'type.in' => '套餐类型不合法',
            'carrier_operator.required' => '请选择运营商',
            'carrier_operator.in' => '运营商不合法',
            'cost_price.numeric' => '套餐价格必须是数字',
            'guide_price.numeric' => '套餐指导价格必须是数字',
            'flows.numeric' => '套餐指导价格必须是数字',
        ];

        Validator::validate($attributes, $rule, $message);

        $attributes['cost_price'] = intval($attributes['cost_price'] * 100);
        $attributes['guide_price'] = intval($attributes['guide_price'] * 100);

        if (!$attributes['id']) {
            $maxId = Package::withTrashed()->max('id');
            $attributes['id'] = $maxId ? $maxId + 1 : 1;
            $node = $this->packageRepository->create($attributes);
        }

        if ($attributes['id']) {
            $node = $this->packageRepository->find($attributes['id']);

            if (!$node) {
                throw new NotExistException('套餐不存在或已删除');
            }

            // 不能修改的字段
            unset($attributes['type']);
            unset($attributes['sn']);
            unset($attributes['carrier_operator']);
            unset($attributes['flows']);

            $this->packageRepository->setModel($node)->update($attributes);
        }

        return $node;
    }

    /**
     * 删除
     *
     * @return bool
     */
    public function destroy($ids)
    {
        $ids = is_array($ids) ? $ids : [$ids];

        $this->packageRepository->destroy($ids);

        return true;
    }

    public static function load($id)
    {
        if (!self::$packages) {
            self::$packages = app(PackageRepository::class)
                ->select(['id', 'type', 'sn', 'name', 'carrier_operator', 'flows', 'flowed', 'service_months', 'status'])
                ->withTrashed()->get()->keyBy('id')->toArray();
        }

        return self::$packages[$id];
    }
}
