package com.pj.tb_trade_area;

import java.io.FileOutputStream;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.pj.api.consts.FeignFactory;
import com.pj.api.dto.DistrictDTO;
import com.pj.current.satoken.StpUserUtil;
import com.pj.tb_goods.TbGoods;
import com.pj.tb_goods.TbGoodsMapper;
import com.pj.tb_people.TbPeople;
import com.pj.utils.so.SoMap;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;
import com.pj.utils.sg.*;
import org.springframework.web.multipart.MultipartFile;

import javax.swing.filechooser.FileSystemView;

/**
 * Service: tb_trade_area -- 贸易区域
 *
 * @author qzy
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class TbTradeAreaService extends ServiceImpl<TbTradeAreaMapper, TbTradeArea> implements IService<TbTradeArea> {

    /**
     * 底层 Mapper 对象
     */
    @Autowired
    TbTradeAreaMapper tbTradeAreaMapper;
    @Autowired
    TbGoodsMapper tbGoodsMapper;
    @Autowired
    private MethodTradeAreaService methodTradeAreaService;

    /**
     * 增
     */
    void add(TbTradeArea t) {
        List<DistrictDTO> districtDTOS = FeignFactory.adminInterface.getDistrictList(t.getAddressIds());
        t.setAddress(districtDTOS.stream().map(DistrictDTO::getDistrict).collect(Collectors.joining()))
                .setCreateTime(new Date()).setCreateName(StpUserUtil.getPCLoginInfo().getLoginName());
        save(t);
    }

    /**
     * 删
     */
    void delete(Long id) {
        removeById(id);
    }

    /**
     * 改
     */
    void update(TbTradeArea t) {
        List<DistrictDTO> districtDTOS = FeignFactory.adminInterface.getDistrictList(t.getAddressIds());
        t.setAddress(districtDTOS.stream().map(DistrictDTO::getDistrict).collect(Collectors.joining()))
                .setUpdateTime(new Date()).setUpdateName(StpUserUtil.getPCLoginInfo().getLoginName());
        updateById(t);

    }

    /**
     * 查
     */
    TbTradeArea getById(String id) {
        return super.getById(id);
    }

    /**
     * 查集合 - 根据条件（参数为空时代表忽略指定条件）
     */
    List<TbTradeArea> getList(SoMap so) {
        return tbTradeAreaMapper.getList(so);
    }

    /**
     * 向商品分类添加商品
     *
     * @author loovi
     * @date
     */
    public int addGoodsToTradeArea(Long tradeAreaId, Long[] goodsIds) {
        // 获取当前登录用户id
//		Long loginId = StpUserUtil.getLoginIdAsLong();
        int line = 0;
        // 获取互市区信息
        TbTradeArea tbTradeArea = tbTradeAreaMapper.selectById(tradeAreaId);
        // 如果互市区不存在则抛异常
        if (Objects.isNull(tbTradeArea)) {
            throw new RuntimeException("该商品类型不存在");
        }
        List<Long> list = Arrays.asList(goodsIds);
        // 添加商品到互市区
        for (Long goodsId : list) {
            TbGoods tbGoods = tbGoodsMapper.selectById(goodsId);
            if (Objects.isNull(tbGoods)) {
                throw new RuntimeException("该商品不存在");
            }
            int i = tbTradeAreaMapper.addGoodsToTradeArea(tradeAreaId, goodsId);
            line = i + 1;
        }
        return line;

    }

    /**
     * 删除商品分类中的商品
     *
     * @author loovi
     * @date
     */
    public int delGoodsFromTradeArea(Long tradeAreaId, Long[] goodsIds) {

        // 获取当前登录用户id
//		Long loginId = StpUserUtil.getLoginIdAsLong();
        int line = 0;
        // 获取互市区信息
        TbTradeArea tbTradeArea = tbTradeAreaMapper.selectById(tradeAreaId);
        // 如果互市区不存在则抛异常
        if (Objects.isNull(tbTradeArea)) {
            throw new RuntimeException("该商品类型不存在");
        }
        List<Long> list = Arrays.asList(goodsIds);
        // 从互市区删除商品
        for (Long goodsId : list) {
            TbGoods tbGoods = tbGoodsMapper.selectById(goodsId);
            if (Objects.isNull(tbGoods)) {
                throw new RuntimeException("该商品不存在");
            }
            int i = tbTradeAreaMapper.delGoodsFromTradeArea(tradeAreaId, goodsId);
            line = i + 1;
        }
        return line;
    }


    /**
     * 导入
     *
     * @param file excel文件
     * @return
     * @throws IOException
     */
    public String importData(MultipartFile file) throws IOException {
        System.out.println("\n开始执行文件上传....\n");

        //判空
        if (file.isEmpty()) return "文件为空,无法执行上传...";
        //获取文件上传数据
        HSSFWorkbook wb = new HSSFWorkbook(file.getInputStream());
        //获取第一页sheet
        HSSFSheet sheet = wb.getSheetAt(0);
        //定义计数器
        int count = 0;
        //定义行对象
        HSSFRow row = null;
        //解析数据封装到集合
        count = methodTradeAreaService.importMethod(row, sheet, count);
        wb.close();
        System.out.println("\n文件上传完成,共上传 " + count + "条 " + "数据...\n");
        return "上传完成,共上传" + count + "条" + "数据。";
    }

    /**
     * 导出 excel文件
     *
     * @param keyword
     * @return
     */
    public String outportExcel(String keyword, String filepath) throws IOException {
        System.out.println("\n开始执行文件导出....\n");
        //导出的文件的路径
        if (filepath == null || filepath.trim().equals("")) {
            // 获取当前用户的桌面路径
            FileSystemView fileSystemView = FileSystemView.getFileSystemView();
            filepath = fileSystemView.getHomeDirectory().getPath();
        }
        filepath = filepath + "\\贸易区域审核数据表_" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + ".xlsx";
        //根据需求查询数据
        List<TbTradeArea> selectedList = tbTradeAreaMapper.selectList(new LambdaQueryWrapper<TbTradeArea>().eq(StringUtils.isNoneBlank(keyword), TbTradeArea::getName, keyword));
        if (selectedList.size() == 0) return "没有可导出的数据。";
        //建立excel对象封装数据
        HSSFWorkbook workbook = new HSSFWorkbook();
        //创建excel表格右下角的sheet页名称
        HSSFSheet sheet = workbook.createSheet("1");
        //创建表头
        HSSFRow row = sheet.createRow(0);
        row.createCell(0).setCellValue("序号");
        row.createCell(1).setCellValue("区域名称");
        row.createCell(2).setCellValue("区域IDs");
        row.createCell(3).setCellValue("地址详情");
        row.createCell(4).setCellValue("地址");

        row.createCell(28).setCellValue("创建时间");
        row.createCell(29).setCellValue("创建人编号");
        row.createCell(30).setCellValue("创建人名称");
        row.createCell(31).setCellValue("更新时间");
        row.createCell(32).setCellValue("更新人编号");
        row.createCell(33).setCellValue("更新人名称");
        row.createCell(34).setCellValue("删除状态");

        //定义计数器
        int count = 0;
        //遍历集合
        for (int i = 0; i < selectedList.size(); i++) {
            HSSFRow sheetRow = sheet.createRow(sheet.getLastRowNum() + 1);
            sheetRow.createCell(0).setCellValue(i + 1);
            sheetRow.createCell(1).setCellValue((selectedList.get(i).getName() + "").equals("null") ? "" : selectedList.get(i).getName() + "");
            sheetRow.createCell(2).setCellValue((selectedList.get(i).getAddressIds() + "").equals("null") ? "" : selectedList.get(i).getAddressIds() + "");
            sheetRow.createCell(3).setCellValue((selectedList.get(i).getDetailAddress() + "").equals("null") ? "" : selectedList.get(i).getDetailAddress() + "");
            sheetRow.createCell(4).setCellValue((selectedList.get(i).getAddress() + "").equals("null") ? "" : selectedList.get(i).getAddress() + "");

            //公共字段
            sheetRow.createCell(22).setCellValue((selectedList.get(i).getCreateTime() + "").equals("null") ? "" : selectedList.get(i).getCreateTime() + "");
            sheetRow.createCell(23).setCellValue((selectedList.get(i).getCreateBy() + "").equals("null") ? "" : selectedList.get(i).getCreateBy() + "");
            sheetRow.createCell(24).setCellValue((selectedList.get(i).getCreateName() + "").equals("null") ? "" : selectedList.get(i).getCreateName() + "");
            sheetRow.createCell(25).setCellValue((selectedList.get(i).getUpdateTime() + "").equals("null") ? "" : selectedList.get(i).getUpdateTime() + "");
            sheetRow.createCell(26).setCellValue((selectedList.get(i).getUpdateBy() + "").equals("null") ? "" : selectedList.get(i).getUpdateBy() + "");
            sheetRow.createCell(27).setCellValue((selectedList.get(i).getUpdateName() + "").equals("null") ? "" : selectedList.get(i).getUpdateName() + "");
            sheetRow.createCell(28).setCellValue((selectedList.get(i).getDeleteStatus() + "").equals("null") ? "" : selectedList.get(i).getDeleteStatus() + "");
            count += 1;
        }
        //建立输出流，输出文件
        FileOutputStream fos = new FileOutputStream(filepath);

        workbook.write(fos);
        fos.flush();
        //关闭输出流
        fos.close();
        workbook.close();
        System.out.println("\n数据导出完成!共导出 " + count + " 条数据。");
        return "数据导出完成!共导出 " + count + " 条数据。";
    }

    public TbTradeArea findByCode(String tradeCode) {
        QueryWrapper<TbTradeArea> ew = new QueryWrapper<>();
        ew.lambda().eq(TbTradeArea::getCode, tradeCode);
        List<TbTradeArea> list = this.list(ew);
        return list.isEmpty() ? null : list.get(0);
    }

    public TbTradeArea updateHandler(String tradeCode, String fieldName) {
        TbTradeArea tbTradeArea = this.findByCode(tradeCode);
        if (tbTradeArea == null) {
            tbTradeArea = new TbTradeArea();
            tbTradeArea.setCode(tradeCode).setName(fieldName).setCreateTime(new Date()).setCreateBy("async");
            this.save(tbTradeArea);
        } else {
            if (!StrUtil.isEmpty(fieldName)){
                tbTradeArea.setName(fieldName)
                        .setUpdateTime(new Date()).setUpdateBy("async");
                this.updateById(tbTradeArea);
            }
        }
        return tbTradeArea;
    }
}
