package com.neusoft.smart.pos.inventory.service;

import com.neusoft.smart.pos.dto.inventory.request.CreateTagRequest;
import com.neusoft.smart.pos.dto.inventory.request.GetTagsRequest;
import com.neusoft.smart.pos.dto.inventory.request.UpdateTagRequest;
import com.neusoft.smart.pos.dto.inventory.response.TagResponse;
import com.neusoft.smart.pos.framework.exception.BusinessCommonException;
import com.neusoft.smart.pos.inventory.constants.GoodsErrorCode;
import com.neusoft.smart.pos.inventory.persistent.domain.InventoryGoodsTag;
import com.neusoft.smart.pos.inventory.persistent.domain.InventoryGoodsTagExample;
import com.neusoft.smart.pos.inventory.persistent.mapper.InventoryGoodsTagMapper;
import com.neusoft.smart.pos.utils.RequestHeaderUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

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

@EnableTransactionManagement
@Service("tagService")
public class TagService {
    
    @Resource
    InventoryGoodsTagMapper inventoryGoodsTagMapper;
    
    public List<TagResponse> selectTags(GetTagsRequest request) {
        InventoryGoodsTagExample example = new InventoryGoodsTagExample();
        example.setOrderByClause("`priority` desc, id desc");
        
        InventoryGoodsTagExample.Criteria criteria = example.createCriteria();
        
        criteria.andDeletedEqualTo(0);
        
        Integer orgId;
        if (request.getOrg() != null) {
            orgId = request.getOrg();
        } else {
            orgId = RequestHeaderUtil.getOrgId();
        }
        criteria.andOrgIdEqualTo(orgId);
        criteria.andShopIdEqualTo(request.getShop() != null ? request.getShop() : 0);
        
        criteria.andIndustryEqualTo(request.getIndustry());
        criteria.andTypeEqualTo(request.getType());
        
        List<TagResponse> list = new ArrayList<>();
        for (InventoryGoodsTag tag : inventoryGoodsTagMapper.selectByExample(example)) {
            TagResponse tagResponse = new TagResponse();
            tagResponse.setId(tag.getId());
            tagResponse.setName(tag.getName());
            tagResponse.setIndustry(tag.getIndustry());
            tagResponse.setOrg(tag.getOrgId());
            tagResponse.setShop(tag.getShopId());
            tagResponse.setType(tag.getType());
            list.add(tagResponse);
        }
        
        return list;
    }
    
    @Transactional
    public TagResponse createTag(CreateTagRequest request) {
        Integer orgId = RequestHeaderUtil.getOrgId();
        Integer shopId = request.getShop() != null ? request.getShop() : 0;
        
        InventoryGoodsTagExample example = new InventoryGoodsTagExample();
        example.createCriteria().andOrgIdEqualTo(orgId)
                .andShopIdEqualTo(shopId)
                .andIndustryEqualTo(request.getIndustry())
                .andTypeEqualTo(request.getType())
                .andDeletedEqualTo(0);
        if (inventoryGoodsTagMapper.countByExample(example) >= 12) {
            throw new BusinessCommonException(GoodsErrorCode.FLAVOR_TAG_MAX_COUNT);
        }
        
        InventoryGoodsTag InventoryGoodsTag = new InventoryGoodsTag();
        InventoryGoodsTag.setName(validateName(request.getName(), orgId, shopId, request.getIndustry(), request.getType(), null));
        InventoryGoodsTag.setIndustry(request.getIndustry());
        InventoryGoodsTag.setType(request.getType());
        InventoryGoodsTag.setOrgId(orgId);
        InventoryGoodsTag.setShopId(shopId);
        InventoryGoodsTag.setPriority(request.getOrder());
        
        Date now = new Date();
        InventoryGoodsTag.setCreatedTime(now);
        InventoryGoodsTag.setUpdatedTime(now);
        
        inventoryGoodsTagMapper.insertSelective(InventoryGoodsTag);
    
        TagResponse tagResponse = new TagResponse();
        tagResponse.setId(InventoryGoodsTag.getId());
        tagResponse.setName(InventoryGoodsTag.getName());
        tagResponse.setIndustry(InventoryGoodsTag.getIndustry());
        tagResponse.setOrg(InventoryGoodsTag.getOrgId());
        tagResponse.setShop(InventoryGoodsTag.getShopId());
        tagResponse.setType(InventoryGoodsTag.getType());
        return tagResponse;
    }
    
    @Transactional
    public void updateTag(Integer id, UpdateTagRequest request) {
        Integer orgId = RequestHeaderUtil.getOrgId();
        Integer shopId = request.getShop();
        
        InventoryGoodsTag InventoryGoodsTag = new InventoryGoodsTag();
        InventoryGoodsTag.setId(id);
        InventoryGoodsTag.setName(validateName(request.getName(), orgId, shopId, request.getIndustry(), request.getType(), id));
        
        inventoryGoodsTagMapper.updateByPrimaryKeySelective(InventoryGoodsTag);
    }
    
    @Transactional
    public void deleteTag(Integer id) {
        InventoryGoodsTag InventoryGoodsTag = new InventoryGoodsTag();
        InventoryGoodsTag.setId(id);
        InventoryGoodsTag.setDeleted(1);
        inventoryGoodsTagMapper.updateByPrimaryKeySelective(InventoryGoodsTag);
    }
    
    public String validateName(String name, Integer org, Integer shop, Integer industry, Integer type, Integer id) {
        if (StringUtils.isEmpty(name)) {
            throw new BusinessCommonException(GoodsErrorCode.EMPTY_CATEGORY_NAME);
        }
        if (name.length() > 10) {
            throw new BusinessCommonException(GoodsErrorCode.FLAVOR_TAG_MAX_LENGTH);
        }
        
        InventoryGoodsTagExample example = new InventoryGoodsTagExample();
        InventoryGoodsTagExample.Criteria criteria = example.createCriteria();
        criteria.andNameEqualTo(name)
                .andOrgIdEqualTo(org)
                .andShopIdEqualTo(shop)
                .andIndustryEqualTo(industry)
                .andTypeEqualTo(type)
                .andDeletedEqualTo(0);
        
        if (id != null) {
            criteria.andIdNotEqualTo(id);
        }
        
        if (inventoryGoodsTagMapper.countByExample(example) > 0) {
            throw new BusinessCommonException(GoodsErrorCode.DUPLICATE_TAG_NAME);
        }
        
        return name;
    }
    
    @Transactional
    public void reorder(Map<Integer, Integer> orderMap) {
        InventoryGoodsTagExample example = new InventoryGoodsTagExample();
        example.createCriteria().andIdIn(new ArrayList<>(orderMap.keySet()));
        
        for (InventoryGoodsTag tag : inventoryGoodsTagMapper.selectByExample(example)) {
            if (!tag.getPriority().equals(orderMap.get(tag.getId()))) {
                tag.setPriority(orderMap.get(tag.getId()));
                tag.setUpdatedTime(new Date());
                inventoryGoodsTagMapper.updateByPrimaryKeySelective(tag);
            }
        }
    }
}
