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

use App\Core\Service;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use App\Exceptions\NotExistException;
use App\Models\Virtual\CompanyAddress;
use App\Exceptions\NotAllowedException;
use Illuminate\Support\Facades\Validator;
use App\Domains\Virtual\Repositories\CompanyRepository;
use App\Domains\Virtual\Repositories\CompanyAddressRepository;

class CompanyAddressService extends Service
{
    protected $companyAddressRepository;

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

    /**
     * 获取企业收货地址
     *
     * @param int $companyId
     * @return Collection
     */
    public function getCompanyAddress($companyId)
    {
        $res = $this->companyAddressRepository->withConditions(['company_id' => $companyId])
            ->orderBy('default', 'desc')
            ->orderBy('updated_at', 'desc')
            ->get();

        return $res;
    }

    /**
     * 设置默认收货地址
     *
     * @param int $companyId
     * @return CompanyAddress
     */
    public function setDefault($id)
    {
        if (!$node = $this->companyAddressRepository->find($id)) {
            throw new NotExistException('地址不存在或已删除');
        }

        DB::transaction(function () use ($node) {
            $this->companyAddressRepository->where(['company_id' => $node->company_id])->update(['default' => 0]);
            $this->companyAddressRepository->setModel($node)->update(['default' => 1]);
        });

        return $node;
    }

    /**
     * 存储收货地址
     *
     * @param array $attributes
     * @return CompanyAddress
     */
    public function store(array $attributes = [])
    {
        $attributes = array_only($attributes, array_merge(app(CompanyAddress::class)->getFillable()));

        $rule = [
            'company_id' => ['required', 'exists:virtual_companies,id'],
            'contacts' => ['required', 'between:2,32'],
            'mobile' => ['required', 'cn_phone'],
            'area' => ['required', 'max:255'],
            'address' => ['required', 'max:255'],
            'default' => ['in:0,1']
        ];

        $message = [
            'company_id.required' => '请输入企业ID',
            'company_id.exists' => '企业不存在或已删除',
            'contacts.required' => '联系人不能为空',
            'contacts.between' => '联系人名称长度不合法',
            'mobile.required' => '手机号不能为空',
            'mobile.cn_phone' => '手机号不合法',
            'area.required' => '请选择区域',
            'address.required' => '请输入详细地址',
        ];

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

        if (!$attributes['id']) {
            if ($this->companyAddressRepository->withConditions($attributes)->count()) {
                throw new NotAllowedException('地址已存在，请勿重复添加');
            }

            $count = $this->companyAddressRepository->withConditions(['company_id' => $attributes['company_id']])->count();

            if ($count >= 10) {
                throw new NotAllowedException('最多添加10个地址');
            }

            if ($count === 0) {
                $attributes['default'] = 1;
            }

            $node = $this->companyAddressRepository->create($attributes);
        }

        if ($attributes['id']) {
            if (!$node = $this->companyAddressRepository->find($attributes['id'])) {
                throw new NotExistException('地址不存在或已删除');
            }

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

        if ($attributes['default']) {
            $this->companyAddressRepository->where('company_id', $attributes['company_id'])
                ->where('id', '<>', $node->id)->update(['default' => 0]);
        }

        app(CompanyRepository::class)->forgetCached();

        return $node;
    }

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

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

        return true;
    }
}
