package net.lab1024.sa.admin.module.business.base.address.service;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import cn.idev.excel.FastExcel;
import net.lab1024.sa.admin.module.business.base.address.dao.AddressDao;
import net.lab1024.sa.admin.module.business.base.address.domain.entity.AddressEntity;
import net.lab1024.sa.admin.module.business.base.address.domain.form.AddressAddForm;
import net.lab1024.sa.admin.module.business.base.address.domain.form.AddressImportForm;
import net.lab1024.sa.admin.module.business.base.address.domain.form.AddressUpdateForm;
import net.lab1024.sa.admin.module.business.base.address.manager.AddressManager;
import net.lab1024.sa.admin.module.business.base.item.domain.entity.ItemEntity;
import net.lab1024.sa.admin.module.business.base.item.domain.form.ItemsImportForm;
import net.lab1024.sa.admin.util.JoinerResult;
import net.lab1024.sa.admin.util.ResponseDTOUtils;
import net.lab1024.sa.base.common.exception.BusinessException;
import net.lab1024.sa.base.common.util.SmartBeanUtil;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.common.util.SmartRequestUtil;
import net.lab1024.sa.base.module.support.dict.constant.DictConst;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import jakarta.annotation.Resource;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

/**
 * 收货地址 Service
 *
 * @author hj
 * @since 2024-12-26 15:35:23
 * copyright 友仓
 */

@Service
public class AddressService {

    @Resource
    private AddressDao addressDao;

    @Resource
    private AddressManager addressManager;

    @Resource
    private AddressQueryService addressQueryService;

    /**
     * 添加
     *
     * @param addForm 添加参数
     * @return ResponseDTO<String>
     */
    @Transactional(rollbackFor = Exception.class)
    public ResponseDTO<String> add(AddressAddForm addForm) {
        AddressEntity addressEntity = SmartBeanUtil.copy(addForm, AddressEntity.class);
        addressDao.insert(addressEntity);

        //更新缓存
        addressManager.removeCache();
        return ResponseDTO.ok();
    }

    /**
     * 更新
     *
     * @param updateForm 更新参数
     * @return ResponseDTO<String>
     */
    @Transactional(rollbackFor = Exception.class)
    public ResponseDTO<String> update(AddressUpdateForm updateForm) {
        AddressEntity addressEntity = SmartBeanUtil.copy(updateForm, AddressEntity.class);
        addressDao.updateById(addressEntity);

        //更新缓存
        addressManager.removeCache();
        return ResponseDTO.ok();
    }

    /**
     * 批量删除
     *
     * @param idList 集合
     * @return ResponseDTO<String>
     */
    @Transactional(rollbackFor = Exception.class)
    public ResponseDTO<String> batchDelete(List<Long> idList) {
        if (CollectionUtils.isEmpty(idList)) {
            return ResponseDTO.ok();
        }

        addressManager.removeBatchByIds(idList);

        //更新缓存
        addressManager.removeCache();
        return ResponseDTO.ok();
    }

    /**
     * 单个删除
     *
     * @param addressId id
     * @return ResponseDTO<String>
     */
    @Transactional(rollbackFor = Exception.class)
    public ResponseDTO<String> delete(Long addressId) {
        if (null == addressId) {
            return ResponseDTO.ok();
        }

        addressDao.deleteById(addressId);
        //更新缓存
        addressManager.removeCache();
        return ResponseDTO.ok();
    }

    /**
     * 收货地址导入
     *
     * @param file 上传文件
     * @return ResponseDTO<String>
     */
    @Transactional(rollbackFor = Exception.class)
    public ResponseDTO<String> importAddress(MultipartFile file) {
        List<AddressImportForm> dataList;
        try {
            dataList = FastExcel.read(file.getInputStream()).head(AddressImportForm.class)
                    .sheet()
                    .doReadSync();
        } catch (IOException e) {
            throw new BusinessException("数据格式存在问题，无法读取");
        }
        if (CollectionUtils.isEmpty(dataList)) {
            return ResponseDTO.userErrorParam("数据为空");
        }

        //获取所有去重后的收货单位
        List<String> addressName = dataList.stream().map(AddressImportForm::getName).distinct().collect(Collectors.toList());

        //查询数据库存在的物料
        Map<String, AddressEntity> exitAddressMap = addressQueryService.queryAddressByNameList(addressName);

        List<AddressEntity> insertToAddress = new ArrayList<>();
        List<AddressEntity> updateToAddress = new ArrayList<>();
        for (AddressImportForm addressImportForm : dataList) {


            //物料
            AddressEntity address = exitAddressMap.get(addressImportForm.getName());

            //物料为空则新增，否则更新
            if (address == null) {
                insertToAddress.add(createAddress(addressImportForm.getName(), addressImportForm.getPerson(), addressImportForm.getTelephone(), addressImportForm.getAddress()));
            } else {
                updateToAddress.add(createAddress(addressImportForm.getName(), addressImportForm.getPerson(), addressImportForm.getTelephone(), addressImportForm.getAddress()));
            }
        }

        JoinerResult resultMsg = JoinerResult.createJoiner();
        return ResponseDTOUtils.buildResponseSussDTO(insertToAddress, updateToAddress, addressManager::saveBatch, addressManager::updateBatchById, resultMsg);
    }

    /**
     * 创建收货地址
     *
     * @param name      收货单位
     * @param person    联系人
     * @param telephone 电话
     * @param address   地址
     * @return AddressEntity
     */
    public AddressEntity createAddress(String name, String person, String telephone, String address) {
        return AddressEntity.builder()
                .name(name)
                .person(person)
                .telephone(telephone)
                .address(address)
                .createUserId(SmartRequestUtil.getRequestUser().getUserId())
                .createUserName(SmartRequestUtil.getRequestUser().getUserName())
                .build();
    }
}
