package com.yeejoin.amos.maintenance.business.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Sequence;
import com.yeejoin.amos.maintenance.business.constants.XJConstant;
import com.yeejoin.amos.maintenance.business.dao.mapper.InputItemMapper;
import com.yeejoin.amos.maintenance.business.dao.mapper.RouteMapper;
import com.yeejoin.amos.maintenance.business.dao.repository.IInputItemDao;
import com.yeejoin.amos.maintenance.business.dao.repository.IPointInputItemDao;
import com.yeejoin.amos.maintenance.business.dto.PictureJsonConfig;
import com.yeejoin.amos.maintenance.business.param.CheckInputParam;
import com.yeejoin.amos.maintenance.business.param.InputItemPageParam;
import com.yeejoin.amos.maintenance.business.service.intfc.ICatalogTreeService;
import com.yeejoin.amos.maintenance.business.service.intfc.IInputItemService;
import com.yeejoin.amos.maintenance.business.util.DaoCriteria;
import com.yeejoin.amos.maintenance.business.vo.InputItemTemplateVo;
import com.yeejoin.amos.maintenance.business.vo.InputItemVo;
import com.yeejoin.amos.maintenance.business.vo.PointInputItemVo;
import com.yeejoin.amos.maintenance.core.util.StringUtil;
import com.yeejoin.amos.maintenance.core.util.query.BaseQuerySpecification;
import com.yeejoin.amos.maintenance.dao.entity.CheckInput;
import com.yeejoin.amos.maintenance.dao.entity.InputItem;
import com.yeejoin.amos.maintenance.feign.RemoteSecurityService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.util.*;

@Service("inputItemService")
public class InputItemServiceImpl implements IInputItemService {

    @Autowired
    IInputItemDao inputItemDao;
    @Autowired
    IPointInputItemDao iPointInputItemDao;
    @Autowired
    RouteMapper routeMapper;
    @Autowired
    InputItemMapper inputItemMapper;

    @Value("${input.custom.prefix}")
    private String customPre;

    @Autowired
    private RemoteSecurityService remoteSecurityService;

    @Autowired
    private Sequence sequence;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public long addNewInputItem(InputItem param) {
        List<PictureJsonConfig> pictureJsonConfigs = JSON.parseArray(param.getPictureJson(), PictureJsonConfig.class);
        for(PictureJsonConfig p: pictureJsonConfigs){
            if(StringUtils.isEmpty(p.getPhotoConfKey())){
                p.setPhotoConfKey(String.valueOf(sequence.nextId()));
            }
        }
        param.setPictureJson(JSONObject.toJSONString(pictureJsonConfigs));
        if (param.getId() > 0) {
            inputItemMapper.updateInputItem(param);
        } else {
            param.setInputType(0);
            param.setItemNo(customPre + param.getItemNo());
            param = inputItemDao.save(param);
        }
        return param.getId();
    }

    @Override
    public InputItem queryInputItemDetail(Long id) {
        return inputItemDao.findById(id).get();
    }

    @Override
    @Transactional
    public void updateInputItem(InputItem param) {
        if (param.getId() <= 0) {
            addNewInputItem(param);
            return;
        }
        inputItemMapper.updateInputItem(param);
    }

    @Override
    @Transactional
    public void delInputItem(Long id) {
        InputItem item = inputItemDao.findById(id).get();
        item.setId(id);
        item.setIsDelete(true);
        inputItemDao.saveAndFlush(item);
    }

    @Override
    public Page<InputItemVo> queryInputItemByPage(InputItemPageParam param) {
        long total = inputItemMapper.countInputItemInfoData(param);
        List<InputItemVo> content = inputItemMapper.getInputItemInfo(param);
        Page<InputItemVo> result = new PageImpl<InputItemVo>(content, param, total);
        return result;
    }

    @Override
    public List<InputItem> queryInputItemByCondition(List<DaoCriteria> criterias) {
        BaseQuerySpecification<InputItem> specification = new BaseQuerySpecification<>(criterias);
        return inputItemDao.findAll(specification);
    }

    @Override
    public int queryInputItemCountByCondition(List<DaoCriteria> criterias) {
        BaseQuerySpecification<InputItem> specification = new BaseQuerySpecification<>(criterias);
        return Integer.parseInt(inputItemDao.count(specification) + "");
    }

    @Override
    @Transactional
    public void saveAs(String[] ids, String userId) {
        for (String itemID : ids) {
            if (ObjectUtils.isEmpty(itemID)) continue;
            InputItem inputItem = inputItemDao.findById(Long.valueOf(itemID)).get();
            InputItem targetInputItem = new InputItem();
            BeanUtils.copyProperties(inputItem, targetInputItem);
            targetInputItem.setId(0);
            targetInputItem.setName(targetInputItem.getName() + "复制");
            targetInputItem.setCreateBy(userId);
            targetInputItem.setCreateDate(new Date());
            if (targetInputItem.getItemNo() != null && targetInputItem.getItemNo().indexOf("-") > 0)
                targetInputItem.setItemNo(targetInputItem.getItemNo().substring(0, targetInputItem.getItemNo().indexOf("-")) + "-" + new Date().getTime());
            else {
                targetInputItem.setItemNo(targetInputItem.getItemNo() + "-" + new Date().getTime());
            }
            inputItemDao.save(targetInputItem);
        }

    }

    @Override
    @Transactional
    public void batchDelInputItem(String[] param) {
        List<Long> ids = new ArrayList<Long>();
        for (int i = 0; i < param.length; i++) {
            ids.add(Long.parseLong(param[i]));
        }
        routeMapper.deleteReleInputItem(param);//1.删除p_route_point_inputitem
        iPointInputItemDao.delPointInputItem(ids);//2.删除p_point_inputitem
        for (String id : param) {//3.删除p_inputItem
            InputItem item = inputItemDao.findById(Long.valueOf(id)).get();
            item.setIsDelete(true);
            inputItemDao.saveAndFlush(item);
        }
    }

    @Override
    public String[] queryInputItemNames(String loginOrgCode) {
        InputItemPageParam param = new InputItemPageParam();
        param.setOrgCode(loginOrgCode);
        List<InputItemVo> content = inputItemMapper.getInputItemInfo(param);
        if (!ObjectUtils.isEmpty(content)) {
            String[] names = new String[content.size()];
            for (int i = 0; i < content.size(); i++) {
                names[i] = content.get(i).getName();
            }
            return names;
        }
        return null;
    }

    @Override
    public List<String> qryItemNoList(List<DaoCriteria> criterias, Long itemId) {
        BaseQuerySpecification<InputItem> spec = new BaseQuerySpecification<>(criterias);
        // 根据过滤条件查询出所有检查项编号
        List<InputItem> itemList = inputItemDao.findAll(spec);
        List<String> itemNoList = new ArrayList<>();
        // 将除去自身以外的所有编号添加到集合中
        for (InputItem item : itemList) {
            if (item.getId() != itemId) {
                itemNoList.add(item.getItemNo());
            }
        }
        return itemNoList;
    }

    @Override
    public Object getMaintenanceClassify(String token, String product, String appKey, String dictCode) {
        JSONArray jsonArray = remoteSecurityService.listDictionaryByDictCode(token, product, appKey, dictCode);
        List list = new LinkedList();
        for (int i = 0, size = jsonArray.size(); i < size; i++) {
            Map<String, String> map = new HashMap<>();
            JSONObject jsonObject = jsonArray.getJSONObject(i);
            map.put("id", jsonObject.get("dictDataKey").toString());
            map.put("name", jsonObject.get("dictDataValue").toString());
            list.add(map);
        }
        return list;
    }

    @Override
    public List<PointInputItemVo> queryCustomInputItem(Map<String, Object> param, String orgCode) {
        param.put("orgCode", orgCode);
        return inputItemMapper.queryCustomInputItem(param);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean uploadListByTemplate(List<InputItemTemplateVo> itemTemplateVoList, String orgCode, String userId) throws Exception {
        List<InputItem> list = new ArrayList<>();
        if (!CollectionUtils.isEmpty(itemTemplateVoList)) {
            itemTemplateVoList.forEach(x -> {
                InputItem inputItem = new InputItem();
                BeanUtils.copyProperties(x, inputItem);
                inputItem.setOrgCode(orgCode);
                inputItem.setCreateDate(new Date());
                inputItem.setOrderNo(0);
                inputItem.setDataJson("{\"OkScore\":0,\"NoScore\":0,\"CheckType\":\"始终合格\"}");
                inputItem.setPictureJson("[]");
                inputItem.setCatalogId(0L);
                inputItem.setIsMust("否");
                inputItem.setIsScore("否");
                inputItem.setIsMultiline("否");
                inputItem.setCreateBy(userId);
                list.add(inputItem);
            });
            Integer integer = insertList(list);
            if (integer > 0) {
                return Boolean.TRUE;
            } else {
                return Boolean.FALSE;
            }
        } else {
            throw new Exception("请填写数据后再上传！");
        }
    }

    @Override
    public Integer insertList(List<InputItem> list) {
        return inputItemMapper.insertList(list);
    }

    @Override
    public Boolean checkIsOk(Long inputItemId, String inputValue) {
        InputItem inputItem = inputItemDao.findById(inputItemId).orElseThrow(() -> new RuntimeException("检查项不存在"));
        CheckInput checkInput = new CheckInput();
        if (XJConstant.INPUT_ITEM_SELECT.equals(inputItem.getItemType())) {
            CheckServiceImpl.paraseSelect(checkInput, inputItem.getDataJson(), new CheckInputParam(inputValue), inputItem.getIsScore());
        } else if (XJConstant.INPUT_ITEM_NUMBER.equals(inputItem.getItemType())) {
            CheckServiceImpl.paraseNumber(checkInput, inputItem.getDataJson(), new CheckInputParam(inputValue), inputItem.getIsScore());
        } else if (XJConstant.INPUT_ITEM_TEXT.equals(inputItem.getItemType())) {
            CheckServiceImpl.paraseText(checkInput, inputItem.getDataJson(), new CheckInputParam(inputValue), inputItem.getIsScore());
        }
        return checkInput.getIsOk().equals(XJConstant.OK);
    }

}
