/*
 * Copyright (c) 京北方信息技术股份有限公司 Corporation 2022 . All rights reserved.
 *
 */
package net.northking.cctp.device.api.brand.service;

import net.northking.cctp.common.db.BasicService;
import net.northking.cctp.common.db.Pagination;
import net.northking.cctp.common.db.annotation.DatabaseReadOnly;
import net.northking.cctp.common.db.annotation.DatabaseWriteOnly;
import net.northking.cctp.common.db.excel.AbstractExcelService;
import net.northking.cctp.common.db.excel.ExcelHeader;
import net.northking.cctp.common.exception.PlatformRuntimeException;
import net.northking.cctp.common.http.QueryByPage;
import net.northking.cctp.common.util.UUIDUtil;

import net.northking.cctp.device.constants.DeviceConstants;
import net.northking.cctp.device.constants.DeviceError;
import net.northking.cctp.device.db.entity.CdDeviceModel;
import net.northking.cctp.device.db.service.CdDeviceModelService;
import net.northking.cctp.device.db.service.CdMobileBrandService;
import net.northking.cctp.device.db.entity.CdMobileBrand;

import net.northking.cctp.device.dto.brand.CdMobileBrandAddDto;
import net.northking.cctp.device.dto.brand.CdMobileBrandDetailDto;
import net.northking.cctp.device.dto.brand.CdMobileBrandQueryDto;
import net.northking.cctp.device.dto.brand.CdMobileBrandUpdateDto;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 移动设备品牌表服务实现类
 *
 * @author maven-cctp-plugin
 * @since 1.0
 */

@Service
@ConditionalOnMissingBean(name = "CdMobileBrandApiServiceImpl")
public class CdMobileBrandApiServiceImpl extends AbstractExcelService<CdMobileBrand> implements CdMobileBrandApiService {
    /**
     * 日志
     */
    private final static Logger logger = LoggerFactory.getLogger(CdMobileBrandApiServiceImpl.class);

    @Autowired
    private CdMobileBrandService cdMobileBrandService;

    @Autowired
    private CdDeviceModelService cdDeviceModelService;

    //= Excel 导入导出相关代码 start ==================//
    @Override
    public BasicService<CdMobileBrand> getService() {
        return this.cdMobileBrandService;
    }

    @Override
    public ExcelHeader[] excelHeaders() {
        ExcelHeader id = new ExcelHeader("主键id", "id", String.class);
        ExcelHeader brandName = new ExcelHeader("品牌名称", "brandName", String.class);
        ExcelHeader brandNameCn = new ExcelHeader("中文名称", "brandNameCn", String.class);
        ExcelHeader brandIcon = new ExcelHeader("品牌标识", "brandIcon", byte[].class);
        ExcelHeader createdBy = new ExcelHeader("创建人", "createdBy", String.class);
        ExcelHeader createdTime = new ExcelHeader("创建时间", "createdTime", Date.class);
        ExcelHeader updatedBy = new ExcelHeader("更新人", "updatedBy", String.class);
        ExcelHeader updatedTime = new ExcelHeader("更新时间", "updatedTime", Date.class);
        return new ExcelHeader[]{};
    }

    /**
     * Excel导入，入库之前的处理
     *
     * @param records 从Excel读取到的记录
     * @return 待入库的记录
     */
    @Override
    protected List<CdMobileBrand> beforeInsertBatch(List<CdMobileBrand> records) {
        for (CdMobileBrand record : records) {
            record.setId(UUIDUtil.create32UUID());
        }
        return records;
    }

    /**
     * 写入Excel之前的处理<br>
     * 数据的特殊处理在此处加工处理
     *
     * @param record 来自数据库记录
     * @return 待写入Excel的记录
     */
    @Override
    protected CdMobileBrand beforeWriteExcel(CdMobileBrand record) {
        return record;
    }

    //= Excel 导入导出相关代码 end =======================//

    //= 增删改查 相关代码 start ==================//
    @Override
    @DatabaseReadOnly
    public Pagination<CdMobileBrandDetailDto> pagingQuery(QueryByPage<CdMobileBrandQueryDto> queryByPage) {
        return this.cdMobileBrandService.pagingQuery(queryByPage);
    }

    @Override
    @DatabaseWriteOnly
    public String add(CdMobileBrandAddDto dto) {
        //品牌名称
        if (StringUtils.isNotEmpty(dto.getBrandName())) {
            if (dto.getBrandName().length()>32){
                throw new PlatformRuntimeException(DeviceError.BRAND_NAME_TOO_LONG);
            }
        }else {
            throw new PlatformRuntimeException(DeviceError.BRAND_NAME_NULL);
        }
        //品牌中文名称
        if (StringUtils.isNotEmpty(dto.getBrandNameCn())) {
            if (dto.getBrandNameCn().length()>32){
                throw new PlatformRuntimeException(DeviceError.BRAND_CHN_NAME_TOO_LONG);
            }
        }else {
            throw new PlatformRuntimeException(DeviceError.BRAND_CHN_NAME_NULL);
        }
        CdMobileBrand entity = new CdMobileBrand();
        String uuid = UUIDUtil.create32UUID();
        entity.setId(uuid);

        //正则表达式校验英文名称
        checkName(dto.getBrandName());

        //校验重名
        CdMobileBrand brand = new CdMobileBrand();
        brand.setBrandName(dto.getBrandName());
        List<CdMobileBrand> brands = this.cdMobileBrandService.query(brand);
        if (brands.size() > 0) {
            throw new PlatformRuntimeException(DeviceError.BRAND_NAME_EXIST, dto.getBrandName());
        }
        entity.setBrandIcon(dto.getBrandIcon());
        entity.setBrandNameCn(dto.getBrandNameCn());
        entity.setBrandName(dto.getBrandName());
        this.cdMobileBrandService.insert(entity);
        return uuid;
    }

    @Override
    @DatabaseWriteOnly
    public Integer updateByPK(CdMobileBrandUpdateDto dto) throws IllegalAccessException {
        CdMobileBrand entity = new CdMobileBrand();
        entity.setId(dto.getId());
        entity.setBrandIcon(dto.getBrandIcon());
        entity.setBrandNameCn(dto.getBrandNameCn());
        return this.cdMobileBrandService.updateByPrimaryKey(entity);
    }

    @Override
    @DatabaseReadOnly
    public CdMobileBrandDetailDto findByPK(String uuid) {
        CdMobileBrand example = new CdMobileBrand();
        example.setId(uuid);
        List<CdMobileBrand> entitys = this.cdMobileBrandService.query(example);
        if (entitys.isEmpty()) {
            return null;
        }

        CdMobileBrandDetailDto dto = new CdMobileBrandDetailDto();
        BeanUtils.copyProperties(entitys.get(0), dto);
        return dto;
    }

    @Override
    @DatabaseWriteOnly
    public Integer deleteByPK(String uuid) {
        CdDeviceModel cdDeviceModel = new CdDeviceModel();
        cdDeviceModel.setBrandId(uuid);
        List<CdDeviceModel> query = this.cdDeviceModelService.query(cdDeviceModel);
        if (query.size() > 0) {
            throw new PlatformRuntimeException(DeviceError.BRAND_MODEL_EXIST);
        }
        CdMobileBrand entity = new CdMobileBrand();
        entity.setId(uuid);
        return this.cdMobileBrandService.deleteByExample(entity);
    }

    @Override
    public List<String> addBatch(List<CdMobileBrandAddDto> batch) {
        List<String> result = new ArrayList<>();
        for (CdMobileBrandAddDto dto : batch) {
            result.add(this.add(dto));
        }
        return result;
    }

    @Override
    public Integer updateBatch(List<CdMobileBrandUpdateDto> batch) throws IllegalAccessException {
        int sum = 0;
        for (CdMobileBrandUpdateDto dto : batch) {
            sum = sum + this.updateByPK(dto);
        }
        return sum;
    }

    @Override
    public Integer deleteBatch(List<Object> batch) {
        return this.cdMobileBrandService.deleteByPrimaryKeys(batch);
    }

    @Override
    public List<CdMobileBrand> queryAllBrand() {
        List<CdMobileBrand> brands = this.cdMobileBrandService.findAllBrand();
        return brands;
    }

    public void checkName(String name) {
        String reg = DeviceConstants.CHECK_NAME_REGEX;
        Pattern p = Pattern.compile(reg);
        Matcher m = p.matcher(name);
        if (!m.find()) {
            throw new PlatformRuntimeException(DeviceError.BRAND_NAME_ERROR, name);
        }
        CdMobileBrand brand = new CdMobileBrand();
        brand.setBrandName(name);
        Integer integer = this.cdMobileBrandService.checkBrand(brand);
        if (integer > 0) {
            throw new PlatformRuntimeException(DeviceError.BRAND_IS_EXIST, name);
        }
    }


}
