package com.yiqi.admin.controller.core;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.yiqi.common.core.page.TableDataInfo;
import com.yiqi.common.exception.ServiceException;
import com.yiqi.common.annotation.Log;
import com.yiqi.common.constant.UrlConstants;
import com.yiqi.common.core.controller.BaseController;
import com.yiqi.common.core.domain.R;
import com.yiqi.common.core.domain.entity.SysDictData;
import com.yiqi.common.enums.*;
import com.yiqi.common.utils.poi.ExcelUtil;
import com.yiqi.core.domain.ClothItem;
import com.yiqi.core.domain.ClothPrice;
import com.yiqi.core.domain.ClothWashMode;
import com.yiqi.core.domain.dto.*;
import com.yiqi.core.domain.vo.*;
import com.yiqi.core.service.IClothItemService;
import com.yiqi.core.service.IClothPriceService;
import com.yiqi.core.service.IClothWashModeRelationService;
import com.yiqi.core.service.IClothWashModeService;
import com.yiqi.system.service.ISysDictDataService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;

@Api(tags = "价格管理")
@RestController
@RequestMapping(value = UrlConstants.managerApi + "/cloth/price")
public class ClothPriceController extends BaseController {

    @Autowired
    private IClothPriceService clothPriceService;
    @Autowired
    private IClothWashModeService clothWashModeService;

    @Autowired
    private ISysDictDataService sysDictDataService;
    @Autowired
    private IClothWashModeRelationService clothWashModeRelationService;

    @Autowired
    private IClothItemService clothItemService;

    @Autowired
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    //<editor-folder desc="衣服管理维度- 价格设置">
    @ApiOperation("获取衣服所有洗衣方式价格")
    @GetMapping(value = "listWashModePriceByClothId")
    public R<List<ClothPriceVO>> listWashModePriceByClothId(@RequestParam @ApiParam("衣服ID") Long clothId) throws Exception {
        return R.ok(clothWashModeRelationService.selectWashModePriceByClothId(clothId));
    }

    @PreAuthorize("@ss.hasPermi('cloth:price:list')")
    @ApiOperation("获取衣服价格明细")
    @GetMapping(value = "/listByClothId")
    public R<List<ClothPriceVO>> listByClothId(@RequestParam @ApiParam("衣服ID") Long clothId, @RequestParam @ApiParam("业务区域ID") Long storeAreaId) throws Exception {
        List<ClothPrice> clothPrices = clothPriceService.list(new QueryWrapper<ClothPrice>().lambda()
                .eq(ClothPrice::getClothId, clothId).eq(ClothPrice::getStoreAreaId, storeAreaId));

        List<ClothWashMode> clothWashModes = clothWashModeService.list(new QueryWrapper<ClothWashMode>().lambda()
                .eq(ClothWashMode::getStatus, StatusType.OK.getCode()).eq(ClothWashMode::getDelFlag, DeleteStatus.OK.getCode()));

        SysDictData sysDictData = new SysDictData();
        sysDictData.setDictType(DictType.cloth_type.getCode());
        sysDictData.setStatus(StatusType.OK.getCode());
        List<SysDictData> dictDatas = sysDictDataService.selectDictDataList(sysDictData);

        List<ClothPriceVO> clothPriceVOS = new ArrayList<>();
        for (ClothWashMode clothWashMode : clothWashModes) {
            ClothPriceVO clothPriceVO = new ClothPriceVO();
            clothPriceVO.setWashModeId(clothWashMode.getId());

            clothPriceVO.setWashModeName(clothWashMode.getName());
            clothPriceVO.setPriceType(ClothPriceType.wash_node.getCode());
            for (ClothPrice clothPrice : clothPrices) {
                if (clothPrice.getPriceType() != null && clothPrice.getPriceType().equals(ClothPriceType.wash_node.getCode()) &&
                        clothPrice.getWashModeId() != null && clothPrice.getWashModeId().equals(clothWashMode.getId())) {
                    clothPriceVO.setPrice(clothPrice.getPrice());
                    break;
                }
            }
            clothPriceVOS.add(clothPriceVO);
        }

        for (SysDictData dictData : dictDatas) {
            ClothPriceVO clothPriceVO = new ClothPriceVO();
            clothPriceVO.setClothTypeCode(dictData.getDictValue());
            clothPriceVO.setClothTypeName(dictData.getDictLabel());
            clothPriceVO.setPriceType(ClothPriceType.cloth_type.getCode());
            for (ClothPrice clothPrice : clothPrices) {
                if (clothPrice.getPriceType() != null && clothPrice.getPriceType().equals(ClothPriceType.cloth_type.getCode())
                        && clothPrice.getClothType() != null && clothPrice.getClothType().equals(Integer.parseInt(dictData.getDictValue()))) {
                    clothPriceVO.setPrice(clothPrice.getPrice());
                    break;
                }
            }
            clothPriceVOS.add(clothPriceVO);
        }

        return R.ok(clothPriceVOS);
    }

    @ApiOperation("设置衣服价格")
    @Transactional(rollbackFor = Exception.class)
    @PostMapping(value = "/setPrice")
    public R setPrice(@Valid @RequestBody ClothPriceDTO clothPriceDTO) throws Exception {
        clothPriceService.remove(new QueryWrapper<ClothPrice>().lambda()
                .eq(ClothPrice::getClothId, clothPriceDTO.getClothId())
                .eq(ClothPrice::getStoreAreaId, clothPriceDTO.getStoreAreaId()));
        List<ClothPrice> clothPrices = new ArrayList<>();
        for (ClothPriceItemDTO clothPriceItemDTO : clothPriceDTO.getClothPriceItemDTOS()) {
            ClothPrice clothPrice = new ClothPrice();
            BeanUtils.copyProperties(clothPriceItemDTO, clothPrice);
            clothPrice.setClothId(clothPriceDTO.getClothId());
            clothPrice.setStoreAreaId(clothPriceDTO.getStoreAreaId());
            clothPrice.setPriceType(Integer.parseInt(clothPriceItemDTO.getPriceType()));
            clothPrice.buildCreateData();
            clothPrices.add(clothPrice);
        }
        clothPriceService.saveBatch(clothPrices);
        return R.ok();
    }

    /**
     * 衣服类型维度 -价格设置- 列表查询
     */
    @ApiOperation("衣服类型维度 - 列表查询")
    @GetMapping(value = "/getClothPriceListByClothType")
    public TableDataInfo getClothPriceListByClothType(@Valid ClothPriceQueryByClothTypeDTO clothPriceQueryByClothTypeDTO) {
        startPage();
        return clothPriceService.getClothPriceListByClothTypeV2(clothPriceQueryByClothTypeDTO);
//        List<ClothPriceQueryByClothTypeVO> list = clothPriceService.getClothPriceListByClothType(clothPriceQueryByClothTypeDTO);
//        for (ClothPriceQueryByClothTypeVO clothPriceQueryByClothTypeVO : list) {
//            clothPriceQueryByClothTypeVO.setTypeName(ClothTypes.getInfoByCode(clothPriceQueryByClothTypeVO.getTypeId()));
//        }
//        return getDataTable(list);
    }

    /**
     * 衣服类型维度 - 设置价格
     */
    @Transactional(rollbackFor = Exception.class)
    @ApiOperation("衣服类型维度 - 设置价格")
    @PostMapping(value = "/setPriceByClothType")
    public R setPriceByClothType(@RequestBody @Valid ClothPriceAddByClothTypeDTO clothPriceAddByClothTypeDTO) {
        ClothPrice clothPrice = clothPriceService.getOne(new QueryWrapper<ClothPrice>().lambda()
                .eq(ClothPrice::getClothId, clothPriceAddByClothTypeDTO.getClothId())
                .eq(ClothPrice::getClothType, clothPriceAddByClothTypeDTO.getClothType())
                .eq(ClothPrice::getPriceType, ClothPriceType.cloth_type.getCode())
                .eq(ClothPrice::getStoreAreaId, clothPriceAddByClothTypeDTO.getStoreAreaId()), Boolean.FALSE);
        if (clothPrice == null) {
            ClothPrice price = new ClothPrice();
            BeanUtils.copyProperties(clothPriceAddByClothTypeDTO, price);
            price.buildCreateData();
            price.setPriceType(ClothPriceType.cloth_type.getCode());
            clothPriceService.save(price);
        } else {
            clothPriceService.update(new UpdateWrapper<ClothPrice>().lambda()
                    .set(ClothPrice::getPrice, clothPriceAddByClothTypeDTO.getPrice())
                    .eq(ClothPrice::getClothId, clothPriceAddByClothTypeDTO.getClothId())
                    .eq(ClothPrice::getClothType, clothPriceAddByClothTypeDTO.getClothType())
                    .eq(ClothPrice::getPriceType, ClothPriceType.cloth_type.getCode())
                    .eq(ClothPrice::getStoreAreaId, clothPriceAddByClothTypeDTO.getStoreAreaId())
            );
        }
        return R.ok();
    }

    /**
     * 衣服类型维度 - 区域价格复制
     */
    @Transactional(rollbackFor = Exception.class)
    @ApiOperation("衣服类型维度 - 区域价格复制")
    @PostMapping(value = "/setPriceByClothTypeCopyArea")
    public R setPriceByClothTypeCopyArea(@RequestBody @Valid ClothPriceByClothTypeCopyAreaDTO clothPriceByClothTypeCopyAreaDTO) {
        if (clothPriceByClothTypeCopyAreaDTO.getStoreAreaIdFrom().equals(clothPriceByClothTypeCopyAreaDTO.getStoreAreaIdTo())) {
            throw new ServiceException("复制区域和选择区域不能相同");
        }
        List<ClothPrice> priceList = clothPriceService.list(new QueryWrapper<ClothPrice>().lambda()
                .eq(ClothPrice::getStoreAreaId, clothPriceByClothTypeCopyAreaDTO.getStoreAreaIdFrom())
                .eq(ClothPrice::getClothType, clothPriceByClothTypeCopyAreaDTO.getClothType())
                .eq(ClothPrice::getPriceType, ClothPriceType.cloth_type.getCode()));
        if (CollUtil.isEmpty(priceList)) {
            throw new ServiceException("选择区域未设置价格，无法复制，请重新选择区域");
        }
        // 删除被复制的区域洗衣方式维度的价格数据
        clothPriceService.remove(new QueryWrapper<ClothPrice>().lambda()
                .eq(ClothPrice::getStoreAreaId, clothPriceByClothTypeCopyAreaDTO.getStoreAreaIdTo())
                .eq(ClothPrice::getClothType, clothPriceByClothTypeCopyAreaDTO.getClothType())
                .eq(ClothPrice::getPriceType, ClothPriceType.cloth_type.getCode()));
        List<ClothPrice> copyList = new ArrayList<>();
        for (ClothPrice clothPrice : priceList) {
            ClothPrice copy = new ClothPrice();
            BeanUtils.copyProperties(clothPrice, copy);
            copy.setPrice(clothPrice.getPrice().multiply(clothPriceByClothTypeCopyAreaDTO.getMultiple()));
            copy.setStoreAreaId(clothPriceByClothTypeCopyAreaDTO.getStoreAreaIdTo());
            copyList.add(copy);
        }
        clothPriceService.saveBatch(copyList);
        return R.ok();
    }
    //</editor-folder>
//<editor-folder desc="洗衣方式维度-价格设置">

    /**
     * 洗衣方式维度 - 列表查询
     */
    @ApiOperation("洗衣方式维度 - 列表查询")
    @GetMapping(value = "/getClothPriceListByWashMode")
    public TableDataInfo getClothPriceListByWashMode(@Valid ClothPriceQueryByWashModeDTO clothPriceQueryByWashModeDTO) {
        startPage();
//        List<ClothPriceQueryByWashModeVO> list = clothPriceService.getClothPriceListByWashMode(clothPriceQueryByWashModeDTO);
//        List<ClothWashMode> washModeList = clothWashModeService.list(new QueryWrapper<ClothWashMode>());
//        Map<Long, String> map = washModeList.stream().collect(Collectors.toMap(ClothWashMode::getId, ClothWashMode::getName));
//        for (ClothPriceQueryByWashModeVO vo : list) {
//            vo.setWashModeName(map.get(vo.getWashModeId()));
//        }
//        return getDataTable(list);
        return clothPriceService.getClothPriceListByWashModeV2(clothPriceQueryByWashModeDTO);
    }

    /**
     * 洗衣方式维度 - 设置价格
     */
    @Transactional(rollbackFor = Exception.class)
    @ApiOperation("洗衣方式维度 - 设置价格")
    @PostMapping(value = "/setPriceByWashMode")
    public R setPriceByWashMode(@RequestBody @Valid ClothPriceAddByWashModeDTO clothPriceAddByWashModeDTO) {
        ClothPrice clothPrice = clothPriceService.getOne(new QueryWrapper<ClothPrice>().lambda()
                .eq(ClothPrice::getClothId, clothPriceAddByWashModeDTO.getClothId())
                .eq(ClothPrice::getWashModeId, clothPriceAddByWashModeDTO.getWashModeId())
                .eq(ClothPrice::getPriceType, ClothPriceType.wash_node.getCode())
                .eq(ClothPrice::getStoreAreaId, clothPriceAddByWashModeDTO.getStoreAreaId()), Boolean.FALSE);
        if (clothPrice == null) {
            ClothPrice price = new ClothPrice();
            BeanUtils.copyProperties(clothPriceAddByWashModeDTO, price);
            price.buildCreateData();
            price.setPriceType(ClothPriceType.wash_node.getCode());
            clothPriceService.save(price);
        } else {
            clothPriceService.update(new UpdateWrapper<ClothPrice>().lambda()
                    .set(ClothPrice::getPrice, clothPriceAddByWashModeDTO.getPrice())
                    .eq(ClothPrice::getClothId, clothPriceAddByWashModeDTO.getClothId())
                    .eq(ClothPrice::getWashModeId, clothPriceAddByWashModeDTO.getWashModeId())
                    .eq(ClothPrice::getPriceType, ClothPriceType.wash_node.getCode())
                    .eq(ClothPrice::getStoreAreaId, clothPriceAddByWashModeDTO.getStoreAreaId())
            );
        }
        return R.ok();
    }

    /**
     * 下载导入洗衣价格模板
     */
    @PostMapping("/downloadTemplate")
    @ApiOperation(value = "下载导入洗衣价格模板")
    public void downloadTemplate(HttpServletResponse response) {
        List<ClothPriceImportVO> importVOList = new ArrayList<>();
        List<ClothItem> list = clothItemService.list(new QueryWrapper<ClothItem>().lambda()
                .eq(ClothItem::getStatus, StatusType.OK.getCode())
                .eq(ClothItem::getDelFlag, StatusType.OK.getCode()));
        if (CollUtil.isNotEmpty(list)) {
            BeanUtils.copyProperties(list, importVOList);
        }
        ExcelUtil<ClothPriceImportVO> util = new ExcelUtil<>(ClothPriceImportVO.class);
        util.exportExcel(response, importVOList, "洗衣价格数据");
    }

    /**
     * 洗衣方式维度 - 导入
     */
    @Log(title = "设置价格-洗衣方式维度-导入", businessType = BusinessType.IMPORT)
    @ApiOperation(value = "导入洗衣价格数据")
    @PostMapping("/importData")
    public R<String> importData(MultipartFile file, ClothPriceImportDTO clothPriceImportDTO) throws Exception {
        if (clothPriceImportDTO.getStoreAreaId() == null) {
            throw new ServiceException("请选择区域");
        }
        ExcelUtil<ClothPriceImportVO> util = new ExcelUtil<>(ClothPriceImportVO.class);
        List<ClothPriceImportVO> priceImportVOS = util.importExcel(file.getInputStream());
        threadPoolTaskExecutor.execute(() -> clothPriceService.importData(priceImportVOS, clothPriceImportDTO));
        return R.ok();
    }


    /**
     * 洗衣方式维度 - 导出
     */
    @Log(title = "洗衣价格数据导出", businessType = BusinessType.EXPORT)
    @PostMapping("/exportData")
    @ApiOperation(value = "导出区域洗衣价格数据")
    public void exportData(HttpServletResponse response, @RequestBody ClothPriceExportDTO clothPriceExportDTO) {
        List<ClothPriceExportVO> list = clothPriceService.getClothPriceListByAreaIdExport(clothPriceExportDTO.getStoreAreaId());
        ExcelUtil<ClothPriceExportVO> util = new ExcelUtil<>(ClothPriceExportVO.class);
        util.exportExcel(response, list, "洗衣价格数据");
    }


    /**
     * 洗衣方式维度 - 区域价格复制
     */
    @Transactional(rollbackFor = Exception.class)
    @ApiOperation("洗衣方式维度 - 区域价格复制")
    @PostMapping(value = "/setPriceByWashModeCopyArea")
    public R setPriceByWashModeCopyArea(@RequestBody @Valid ClothPriceByWashModeCopyAreaDTO clothPriceByWashModeCopyAreaDTO) {
        if (clothPriceByWashModeCopyAreaDTO.getStoreAreaIdFrom().equals(clothPriceByWashModeCopyAreaDTO.getStoreAreaIdTo())) {
            throw new ServiceException("复制区域和选择区域不能相同");
        }
        List<ClothPrice> priceList = clothPriceService.list(new QueryWrapper<ClothPrice>().lambda()
                .eq(ClothPrice::getStoreAreaId, clothPriceByWashModeCopyAreaDTO.getStoreAreaIdFrom())
                .eq(ClothPrice::getPriceType, ClothPriceType.wash_node.getCode()));
        if (CollUtil.isEmpty(priceList)) {
            throw new ServiceException("选择区域未设置价格，无法复制，请重新选择区域");
        }
        // 删除被复制的区域洗衣方式维度的价格数据
        clothPriceService.remove(new QueryWrapper<ClothPrice>().lambda()
                .eq(ClothPrice::getStoreAreaId, clothPriceByWashModeCopyAreaDTO.getStoreAreaIdTo())
                .eq(ClothPrice::getPriceType, ClothPriceType.wash_node.getCode()));
        List<ClothPrice> copyList = new ArrayList<>();
        for (ClothPrice clothPrice : priceList) {
            ClothPrice copy = new ClothPrice();
            BeanUtils.copyProperties(clothPrice, copy);
            copy.setPrice(clothPrice.getPrice().multiply(clothPriceByWashModeCopyAreaDTO.getMultiple()));
            copy.setStoreAreaId(clothPriceByWashModeCopyAreaDTO.getStoreAreaIdTo());
            copyList.add(copy);
        }
        clothPriceService.saveBatch(copyList);
        return R.ok();
    }
}
























