package com.hfkj.service.impl;

import com.hfkj.common.exception.ErrorCode;
import com.hfkj.common.exception.ErrorHelp;
import com.hfkj.common.exception.SysCode;
import com.hfkj.common.security.UserCenter;
import com.hfkj.dao.BsDeviceMapper;
import com.hfkj.entity.*;
import com.hfkj.model.UserInfoModel;
import com.hfkj.service.*;
import com.hfkj.sysenum.DeviceOpTypeEnum;
import com.hfkj.sysenum.DeviceStatusEnum;
import com.hfkj.sysenum.MerStatusEnum;
import com.hfkj.sysenum.StoreStatusEnum;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service("deviceService")
public class BsDeviceServiceImpl implements BsDeviceService {

    @Resource
    private UserCenter userCenter;

    @Resource
    private BsCompanyService companyService;

    @Resource
    private BsAgentService agentService;

    @Resource
    private BsSalesmanService salesmanService;

    @Resource
    private BsMerService merService;

    @Resource
    private BsStoreService storeService;

    @Resource
    private BsDeviceMapper deviceMapper;

    @Resource
    private BsDeviceOperateLogService deviceOperateLogService;

    @Override
    public void addDevice(BsDevice device) {
        UserInfoModel userModel = userCenter.getSessionModel(UserInfoModel.class);
        if (userModel == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.SEC_USER_EXPIRED, "");
        }

        device.setOpUserId(userModel.getSecUser().getId());
        device.setOpUserName(userModel.getSecUser().getUserName());
        editDevice(device);

        // 设备操作日志
        deviceOperateLogService.insertLog(device.getId(),
                DeviceOpTypeEnum.type1,
                "新增设备",
                device.getOpUserId(),
                device.getOpUserName(),
                device.getId());
    }

    @Override
    public void updateDevice(BsDevice device) {
        UserInfoModel userModel = userCenter.getSessionModel(UserInfoModel.class);
        if (userModel == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.SEC_USER_EXPIRED, "");
        }

        editDevice(device);

        // 设备操作日志
        deviceOperateLogService.insertLog(device.getId(),
                DeviceOpTypeEnum.type2,
                "修改设备",
                device.getOpUserId(),
                device.getOpUserName(),
                device.getId());
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
    public void batchBindCompany(List<Long> deviceIdList, Long companyId) {
        for (Long id : deviceIdList) {
            bindCompany(id, companyId);
        }
    }

    @Override
    public void bindCompany(Long deviceId, Long companyId) {
        // 设备
        BsDevice device = getDetail(deviceId);
        if (device == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到设备信息");
        }
        if (!device.getStatus().equals(DeviceStatusEnum.status1.getNumber())) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "设备状态异常");
        }
        if (device.getCompanyId() != null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "设备编号" + device.getDeviceNo() + ",无法分配，设备分配给其他公司");
        }
        // 门店
        BsCompany company = companyService.getCompanyById(companyId);
        if (company == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到公司信息");
        }
        device.setCompanyId(company.getId());
        device.setCompanyName(company.getName());
        editDevice(device);

        // 设备操作日志
        deviceOperateLogService.insertLog(device.getId(),
                DeviceOpTypeEnum.type4,
                "分配设备",
                device.getOpUserId(),
                device.getOpUserName(),
                device.getCompanyId());
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
    public void batchBindAgent(List<Long> deviceIdList, Long agentId) {
        for (Long id : deviceIdList) {
            bindAgent(id, agentId);
        }
    }

    @Override
    public void bindAgent(Long deviceId, Long agentId) {
        // 设备
        BsDevice device = getDetail(deviceId);
        if (device == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到设备信息");
        }
        if (!device.getStatus().equals(DeviceStatusEnum.status1.getNumber())) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "设备状态异常");
        }
        if (device.getAgentId() != null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "设备编号" + device.getDeviceNo() + ",无法分配，设备分配给其他代理商");
        }
        // 门店
        BsAgent agent = agentService.getAgent(agentId);
        if (agent == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到代理商信息");
        }
        device.setAgentId(agent.getId());
        device.setAgentName(agent.getName());
        editDevice(device);

        // 设备操作日志
        deviceOperateLogService.insertLog(device.getId(),
                DeviceOpTypeEnum.type6,
                "分配设备",
                device.getOpUserId(),
                device.getOpUserName(),
                device.getAgentId());
    }

    @Override
    public void batchBindSalesman(List<Long> deviceIdList, Long salesmanId) {
        for (Long id : deviceIdList) {
            bindSalesman(id, salesmanId);
        }
    }

    @Override
    public void bindSalesman(Long deviceId, Long salesmanId) {
        // 设备
        BsDevice device = getDetail(deviceId);
        if (device == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到设备信息");
        }
        if (!device.getStatus().equals(DeviceStatusEnum.status1.getNumber())) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "设备状态异常");
        }
        if (device.getSalesmanId() != null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "设备编号" + device.getDeviceNo() + "，设备已分配给其他业务员");
        }
        // 业务员
        BsSalesman salesman = salesmanService.getSalesman(salesmanId);
        if (salesman == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到门店信息");
        }
        device.setSalesmanId(salesman.getId());
        device.setSalesmanName(salesman.getName());
        editDevice(device);

        // 设备操作日志
        deviceOperateLogService.insertLog(device.getId(),
                DeviceOpTypeEnum.type8,
                "分配设备",
                device.getOpUserId(),
                device.getOpUserName(),
                device.getSalesmanId());
    }

    @Override
    public void batchUnbindSalesman(List<Long> deviceIdList) {
        for (Long id : deviceIdList) {
            unbindSalesman(id);
        }
    }

    @Override
    public void unbindSalesman(Long deviceId) {
        UserInfoModel userModel = userCenter.getSessionModel(UserInfoModel.class);
        if (userModel == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.SEC_USER_EXPIRED, "");
        }
        // 设备
        BsDevice device = getDetail(deviceId);
        if (device == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到设备信息");
        }
        if (!device.getStatus().equals(DeviceStatusEnum.status1.getNumber())) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "设备状态异常");
        }
        if (device.getStoreId() == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "无法解绑，未绑定门店");
        }

        // 设备操作日志
        deviceOperateLogService.insertLog(device.getId(),
                DeviceOpTypeEnum.type9,
                "设备解绑",
                device.getOpUserId(),
                device.getOpUserName(),
                device.getSalesmanId());

        device.setSalesmanId(null);
        device.setSalesmanName(null);
        device.setMerId(null);
        device.setMerName(null);
        device.setStoreId(null);
        device.setStoreName(null);
        editDevice(device);

    }

    @Override
    public void bindStore(Long deviceId, Long storeId) {
        // 设备
        BsDevice device = getDetail(deviceId);
        if (device == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到设备信息");
        }
        if (!device.getStatus().equals(DeviceStatusEnum.status1.getNumber())) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "设备状态异常");
        }
        if (device.getStoreId() != null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "无法绑定，设备已绑定其他门店");
        }

        // 门店
        BsStore store = storeService.getStoreById(storeId);
        if (store == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到门店信息");
        }
        if (!store.getStatus().equals(StoreStatusEnum.status2.getNumber())) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "门店状态异常");
        }

        // 商户
        BsMer mer = merService.getMer(store.getMerId());
        if (mer == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "位置商户信息");
        }
        if (!mer.getMerStatus().equals(MerStatusEnum.status1.getNumber())) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "商户状态异常");
        }

        device.setMerId(mer.getId());
        device.setMerName(mer.getMerName());
        device.setStoreId(storeId);
        device.setStoreName(store.getName());
        device.setBindStatus(true);
        device.setBindTime(new Date());
        editDevice(device);

        // 设备操作日志
        deviceOperateLogService.insertLog(device.getId(),
                DeviceOpTypeEnum.type10,
                "分配设备",
                device.getOpUserId(),
                device.getOpUserName(),
                device.getStoreId());
    }

    @Override
    public void unbindStore(Long deviceId) {
        UserInfoModel userModel = userCenter.getSessionModel(UserInfoModel.class);
        if (userModel == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.SEC_USER_EXPIRED, "");
        }
        // 设备
        BsDevice device = getDetail(deviceId);
        if (device == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到设备信息");
        }
        if (!device.getStatus().equals(DeviceStatusEnum.status1.getNumber())) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "设备状态异常");
        }
        if (device.getStoreId() == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "无法解绑，未绑定门店");
        }
        // 设备操作日志
        deviceOperateLogService.insertLog(device.getId(),
                DeviceOpTypeEnum.type11,
                "设备解绑",
                device.getOpUserId(),
                device.getOpUserName(),
                device.getStoreId());

        device.setMerId(null);
        device.setMerName(null);
        device.setStoreId(null);
        device.setStoreName(null);
        device.setBindStatus(false);
        device.setBindTime(null);
        editDevice(device);


    }

    @Override
    public void editDevice(BsDevice device) {
        if (device.getId() == null) {
            device.setStatus(1);
            device.setCreateTime(new Date());
            device.setUpdateTime(new Date());
            deviceMapper.insert(device);
        } else {
            device.setUpdateTime(new Date());
            deviceMapper.updateByPrimaryKey(device);
        }
    }

    @Override
    public BsDevice getDetailByNo(String deviceNo) {
        BsDeviceExample example = new BsDeviceExample();
        example.createCriteria().andDeviceNoEqualTo(deviceNo).andStatusNotEqualTo(DeviceStatusEnum.status0.getNumber());
        List<BsDevice> list = deviceMapper.selectByExample(example);
        if (list.size() > 0) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public BsDevice getDetail(Long deviceId) {
        return deviceMapper.selectByPrimaryKey(deviceId);
    }

    @Override
    public List<BsDevice> getDeviceList(Map<String, Object> param) {
        BsDeviceExample example = new BsDeviceExample();
        BsDeviceExample.Criteria criteria = example.createCriteria()
                .andStatusNotEqualTo(DeviceStatusEnum.status0.getNumber());

        if (MapUtils.getLong(param, "companyId") != null) {
            criteria.andCompanyIdEqualTo(MapUtils.getLong(param, "companyId"));
        }

        if (StringUtils.isNotBlank(MapUtils.getString(param, "companyName"))) {
            criteria.andCompanyNameEqualTo("%" + MapUtils.getString(param, "companyName") + "%");
        }

        if (MapUtils.getLong(param, "agentId") != null) {
            criteria.andAgentIdEqualTo(MapUtils.getLong(param, "agentId"));
        }

        if (StringUtils.isNotBlank(MapUtils.getString(param, "agentName"))) {
            criteria.andAgentNameLike("%" + MapUtils.getString(param, "agentName") + "%");
        }

        if (MapUtils.getLong(param, "salesmanId") != null) {
            criteria.andSalesmanIdEqualTo(MapUtils.getLong(param, "salesmanId"));
        }

        if (StringUtils.isNotBlank(MapUtils.getString(param, "salesmanName"))) {
            criteria.andSalesmanNameLike("%" + MapUtils.getString(param, "salesmanName") + "%");
        }

        if (MapUtils.getLong(param, "merId") != null) {
            criteria.andMerIdEqualTo(MapUtils.getLong(param, "merId"));
        }

        if (StringUtils.isNotBlank(MapUtils.getString(param, "merName"))) {
            criteria.andMerNameLike("%" + MapUtils.getString(param, "merName") + "%");
        }

        if (MapUtils.getLong(param, "storeId") != null) {
            criteria.andStoreIdEqualTo(MapUtils.getLong(param, "storeId"));
        }

        if (StringUtils.isNotBlank(MapUtils.getString(param, "storeName"))) {
            criteria.andStoreNameLike("%" + MapUtils.getString(param, "storeName") + "%");
        }

        if (MapUtils.getInteger(param, "deviceType") != null) {
            criteria.andDeviceTypeEqualTo(MapUtils.getInteger(param, "deviceType"));
        }

        if (StringUtils.isNotBlank(MapUtils.getString(param, "deviceNo"))) {
            criteria.andDeviceNoLike("%" + MapUtils.getString(param, "deviceNo") + "%");
        }

        if (MapUtils.getInteger(param, "status") != null) {
            criteria.andStatusEqualTo(MapUtils.getInteger(param, "status"));
        }

        if (MapUtils.getBoolean(param, "buildStatus") != null) {
            criteria.andBindStatusEqualTo(MapUtils.getBoolean(param, "buildStatus"));
        }

        if (MapUtils.getBoolean(param, "isAssignStore") != null) {
            // 是否已分配给门店
            if (MapUtils.getBoolean(param, "isAssignStore") == true) {
                criteria.andStoreIdIsNotNull();
            } else {
                criteria.andStoreIdIsNull();
            }
        }

        example.setOrderByClause("create_time desc");
        return deviceMapper.selectByExample(example);
    }
}
