<?php

declare (strict_types=1);

namespace app\admin\service\store;

use app\admin\model\Store;
use app\admin\service\admin\User as AdminUserService;
use app\common\enum\equipment\EquipmentType;
use app\common\service\BaseService;
use app\common\model\Equipment as EquipmentModel;
use app\admin\validate\Equipment as EquipmentValidate;
use app\common\database\Dm;
use think\facade\Db;

class Equipment extends BaseService
{
    public $id;
    public function add(array $param)
    {
        $this->validate($param);
        if (EquipmentModel::checkExist('name',$param['name'])) {
            $this->error = '设备名称已存在';
            return false;
        }
        if (EquipmentModel::checkExist('code',$param['code'])) {
            $this->error = '设备号已存在';
            return false;
        }
        // 当前登录用户
        $loginInfo = AdminUserService::getLoginInfo();

        $param['create_by'] = $loginInfo['user']['user_name'];
        $model = new EquipmentModel();
        $res = $model->add($param);
        $this->id = $model['id'] ?: 0;
        return $res;
    }

    private function validate(array $data): void
    {
        // 数据验证
        $validate = new EquipmentValidate();
        if (!$validate->check($data)) {
            throwError($validate->getError());
        }
    }

    public function detail(int $id): array
    {
        $infos = EquipmentModel::detail($id);
        if (empty($infos)){
            return [];
        }
        $type = EquipmentType::data();
        $store_all = Store::getAllData(['is_delete' => 0],'store_id,store_name');
        $store_infos = array_column($store_all,'store_name','store_id');
        $infos = $infos->toArray();
        $infos['type_name'] = $type[$infos['type']]['name'] ?? '';
        $infos['store_name'] = $store_infos[$infos['store_id']] ?? '';
        return $this->readonlyResponseRow($infos);
    }

    public function getList($param): array
    {
        $where = [['is_delete','=',0]];
        if (!empty($param['type'])){
            $where[] = ['type','=',$param['type']];
        }
        $type = EquipmentType::data();
        $lists = EquipmentModel::getList($where);
        $lists['data'] = array_map(function ($item) use ($type) {
            $item['type_name'] = $type[$item['type']]['name'] ?? '';
            return $this->readonlyResponseRow($item);
        },$lists['data']);
        return $lists;
    }

    public function getCode($id): array
    {
        $matecode = '';
        $flag = true;
        while($flag) {
            $matecode = $this->random(6, 3);
            $matecode_exist = EquipmentModel::checkExist('matecode',$matecode);
            if(!$matecode_exist) {
                $flag = false;
            }
        }
        $update = EquipmentModel::update(['matecode' => $matecode, 'mate_flag' => 0],['id' => $id]);
        if ($update === false){
            throwError('设备编号生成失败');
        }
        return ['code' => $matecode];
    }

    public function random(int $length, int $type = 1, string $chars = '0123456789abcdefghijklmnopqrstuvwxyz') {
        if($type == 1) {
            $hash = sprintf('%0'.$length.'d', mt_rand(0, pow(10, $length) - 1));
        } else {
            $hash = '';
            if($type == 3) $chars .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
            $max = strlen($chars) - 1;
            for($i = 0; $i < $length; $i++) $hash .= $chars[mt_rand(0, $max)];
        }
        return $hash;
    }

    public function setDelete($id): bool
    {
        $del = EquipmentModel::setDelete($id);
        if ($del === false){
            throwError('设备删除失败');
        }
        return true;
    }

    public function edit(array $param): bool
    {
        $detail = EquipmentModel::detail($param['id']);
        if (empty($detail)){
            throwError('设备不存在');
        }
        if (EquipmentModel::checkExist('name',$param['name'],[['is_delete','=',0],['id','<>',$param['id']]])) {
            $this->error = '设备名称已存在';
            return false;
        }
        if (EquipmentModel::checkExist('code',$param['code'],[['is_delete','=',0],['id','<>',$param['id']]])) {
            $this->error = '设备号已存在';
            return false;
        }
        $id = $param['id'];
        unset($param['id']);
        $update = EquipmentModel::update($param,['id' => $id]);
        if ($update === false){
            throwError('设备编辑失败');
        }
        return true;
    }

    public function getStoreList()
    {
        $lists = Store::getAllData(['is_delete' => 0],'store_id,store_name');
        return $lists;
    }

    /** Match the source DATETIME(0) wire only for observed zero DM fractions. */
    private function readonlyResponseRow(array $row): array
    {
        if (Db::connect() instanceof Dm
            && isset($row['mate_time']) && is_string($row['mate_time'])
            && preg_match('/^(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})\.0{1,6}$/D', $row['mate_time'], $matches) === 1) {
            $row['mate_time'] = $matches[1];
        }
        return $row;
    }
}
