package com.sqx.modules.address.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sqx.common.exception.SqxException;
import com.sqx.common.utils.Constant;
import com.sqx.common.utils.PageUtils;
import com.sqx.common.validator.ValidatorUtils;
import com.sqx.modules.address.dao.InsideAddressDao;
import com.sqx.modules.address.dto.InsideAddressDTO;
import com.sqx.modules.address.entity.InsideAddress;
import com.sqx.modules.address.query.InsideAddressQuery;
import com.sqx.modules.address.service.InsideAddressService;
import com.sqx.modules.address.vo.InsideAddressVO;
import com.sqx.modules.riderStation.entity.RiderStation;
import com.sqx.modules.riderStation.service.RiderStationService;
import com.sqx.modules.utils.excel.EasyExcelUtil;
import com.sqx.modules.utils.excel.ExcelFinishCallBack;
import com.sqx.modules.utils.excel.ExcelUtils;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author codingliang
 * @date 2025-09-13
 */
@Service
public class InsideAddressServiceImpl extends ServiceImpl<InsideAddressDao, InsideAddress> implements InsideAddressService {

    @Autowired
    RiderStationService riderStationService;

    @Override
    public PageUtils pages(InsideAddressQuery query) {
        Page<InsideAddress> page = new Page<>(query.getPage(), query.getLimit());
        IPage<InsideAddressVO> data = baseMapper.selectPages(page, query);
        return new PageUtils(data);
    }

    @Override
    public void addInsideAddress(InsideAddressDTO insideAddressDTO) {
        // 地址详情不能重复
        checkAddressUnique(insideAddressDTO);

        // 新增内部地址
        InsideAddress insideAddress = new InsideAddress();
        BeanUtil.copyProperties(insideAddressDTO, insideAddress);
        insideAddress.setDelFlag(Constant.NO);
        insideAddress.setCreateTime(new Date());
        insideAddress.setUpdateTime(new Date());
        baseMapper.insert(insideAddress);
    }

    @Override
    public void updateInsideAddress(InsideAddressDTO insideAddressDTO) {
        // 地址详情不能重复
        checkAddressUnique(insideAddressDTO);

        // 更新内部地址
        InsideAddress insideAddress = new InsideAddress();
        BeanUtil.copyProperties(insideAddressDTO, insideAddress);
        insideAddress.setUpdateTime(new Date());
        baseMapper.updateById(insideAddress);
    }

    @Override
    @Transactional
    public void deleteByIds(List<Long> ids) {
        removeByIds(ids);
    }

    @Override
    public List<InsideAddress> listByStationId(Long stationId) {
        List<InsideAddress> list = baseMapper.selectList(new LambdaQueryWrapper<InsideAddress>()
                .eq(InsideAddress::getStationId, stationId)
                .eq(InsideAddress::getStatus, Constant.YES)
                .orderByAsc(InsideAddress::getSort));

//        精简数据缺少
//        List<InsideAddressShortVO> vos = list.stream().map(item -> {
//            InsideAddressShortVO vo = new InsideAddressShortVO();
//            BeanUtil.copyProperties(item, vo);
//            return vo;
//        }).collect(Collectors.toList());

        return list;
    }

    @Override
    public void exportData(InsideAddressQuery query) {
        Page<InsideAddress> page = new Page<>(query.getPage(), query.getLimit());
        IPage<InsideAddressVO> data = baseMapper.selectPages(page, query);

        // 导出数据
        List<InsideAddressVO> list = data.getRecords();

        list.forEach(item -> {
            item.setStatus(item.getStatus() == Constant.YES ? "正常" : "停用");
        });

        EasyExcelUtil.exportExcel(list, InsideAddressVO.class, "内部地址", "sheet1");
    }

    @Override
    public List<InsideAddressVO> exportShippingAddress(InsideAddressQuery query) {
        return baseMapper.exportShippingAddress(query);
    }

    @Override
    public void importData(MultipartFile file) throws IOException, ParseException {
        InputStream inputStream = file.getInputStream();
        XSSFWorkbook sheets = new XSSFWorkbook(inputStream);
        //读取第一张sheet
        XSSFSheet sheetAt = sheets.getSheetAt(0);
        DataFormatter dataFormatter = new DataFormatter();
        ArrayList<InsideAddress> insideAddresses = new ArrayList<>();
        for (int rowNum = 0; rowNum < sheetAt.getLastRowNum() + 1; rowNum++) {
            XSSFRow row = sheetAt.getRow(rowNum);
            if (row != null) {
                if (rowNum == 0) {
                    String stationName = dataFormatter.formatCellValue(row.getCell(0));//骑手站点
                    if (!stationName.equals("骑手站点")) {
                        throw new SqxException("导入数据第一列为骑手站点");
                    }
                    String province = dataFormatter.formatCellValue(row.getCell(1));//省
                    if (!province.equals("省")) {
                        throw new SqxException("导入数据第二列为省");
                    }
                    String city = dataFormatter.formatCellValue(row.getCell(2));//市
                    if (!city.equals("市")) {
                        throw new SqxException("导入数据第三列为市");
                    }
                    String district = dataFormatter.formatCellValue(row.getCell(3));//区/县
                    if (!district.equals("区/县")) {
                        throw new SqxException("导入数据第四列为区/县");
                    }
                    String addressDetail = dataFormatter.formatCellValue(row.getCell(4));//地址名
                    if (!addressDetail.equals("地址名")) {
                        throw new SqxException("导入数据第五列为地址名");
                    }
                    String lng = dataFormatter.formatCellValue(row.getCell(5));//经度
                    if (!lng.equals("经度")) {
                        throw new SqxException("导入数据第六列为经度");
                    }
                    String lat = dataFormatter.formatCellValue(row.getCell(6));//纬度
                    if (!lat.equals("纬度")) {
                        throw new SqxException("导入数据第列七为纬度");
                    }
                    String deliveryFee = dataFormatter.formatCellValue(row.getCell(7));//地址配送费
                    if (!deliveryFee.equals("地址配送费")) {
                        throw new SqxException("导入数据第列七为地址配送费");
                    }
                    String sort = dataFormatter.formatCellValue(row.getCell(8));//排序
                    if (!sort.equals("排序")) {
                        throw new SqxException("导入数据第列七为排序");
                    }
                    String status = dataFormatter.formatCellValue(row.getCell(9));//是否启用
                    if (!status.equals("是否启用")) {
                        throw new SqxException("导入数据第列七为是否启用");
                    }

                }else {
                    InsideAddress insideAddress = new InsideAddress();
                    String stationName = dataFormatter.formatCellValue(row.getCell(0));//骑手站点
                    if (ObjectUtils.isNotEmpty(stationName)) {
                        RiderStation riderStation=riderStationService.getName(stationName);
                        if (ObjectUtils.isNotEmpty(riderStation)) {
                            insideAddress.setStationId(riderStation.getId());
                        }else {
                            int h = rowNum + 1;
                            throw new SqxException("第" + h + "行,骑手站点不存在");
                        }
                    }else {
                        int h = rowNum + 1;
                        throw new SqxException("第" + h + "行,骑手站点为空");
                    }
                    String province = dataFormatter.formatCellValue(row.getCell(1));//省
                    if (ObjectUtils.isNotEmpty(province)) {
                        insideAddress.setProvince(province);
                    }else {
                        int h = rowNum + 1;
                        throw new SqxException("第" + h + "行,省为空");
                    }

                    String city = dataFormatter.formatCellValue(row.getCell(2));//市
                    if (ObjectUtils.isNotEmpty(city)) {
                        insideAddress.setCity(city);
                    }else {
                        int h = rowNum + 1;
                        throw new SqxException("第" + h + "行,市为空");
                    }

                    String district = dataFormatter.formatCellValue(row.getCell(3));//区/县
                    if (ObjectUtils.isNotEmpty(district)) {
                        insideAddress.setDistrict(district);
                    }else {
                        int h = rowNum + 1;
                        throw new SqxException("第" + h + "行,市为空");
                    }

                    String addressDetail = dataFormatter.formatCellValue(row.getCell(4));//地址名
                    if (ObjectUtils.isNotEmpty(addressDetail)) {
//                        判断地址是否重复
                        long count = baseMapper.selectCount(new LambdaQueryWrapper<InsideAddress>()
                                .eq(InsideAddress::getAddressDetail, addressDetail));
                        if (count > 0) {
                            throw new SqxException("地址详情不能重复");
                        }
                        insideAddress.setAddressDetail(addressDetail);
                    }else {
                        int h = rowNum + 1;
                        throw new SqxException("第" + h + "行,地址名为空");
                    }

                    String lng = dataFormatter.formatCellValue(row.getCell(5));//经度
                    if (ObjectUtils.isNotEmpty(lng)) {
                        insideAddress.setLng(Double.valueOf(lng));
                    }else {
                        int h = rowNum + 1;
                        throw new SqxException("第" + h + "行,经度为空");
                    }

                    String lat = dataFormatter.formatCellValue(row.getCell(6));//纬度
                    if (ObjectUtils.isNotEmpty(lat)) {
                        insideAddress.setLat(Double.valueOf(lat));
                    }else {
                        int h = rowNum + 1;
                        throw new SqxException("第" + h + "行,纬度为空");
                    }

                    String deliveryFee = dataFormatter.formatCellValue(row.getCell(7));//地址配送费
                    if (ObjectUtils.isNotEmpty(deliveryFee)) {
                        insideAddress.setDeliveryFee(new BigDecimal(deliveryFee));
                    }else {
                        int h = rowNum + 1;
                        throw new SqxException("第" + h + "行,地址配送费为空");
                    }

                    String sort = dataFormatter.formatCellValue(row.getCell(8));//排序
                    if (ObjectUtils.isNotEmpty(sort)) {
                        insideAddress.setSort(Integer.valueOf(sort));
                    }else {
                        int h = rowNum + 1;
                        throw new SqxException("第" + h + "行,排序为空");
                    }

                    String status = dataFormatter.formatCellValue(row.getCell(9));//是否启用
                    if (ObjectUtils.isNotEmpty(status)) {
                        if (status.equals("启用")) {
                            insideAddress.setStatus("1");
                        }else {
                            insideAddress.setStatus("0");
                        }
                    }else {
                        int h = rowNum + 1;
                        throw new SqxException("第" + h + "行,是否启用为空");
                    }

                    insideAddress.setDelFlag(Constant.NO);
                    insideAddress.setCreateTime(new Date());
                    insideAddress.setUpdateTime(new Date());

                    insideAddresses.add(insideAddress);
                }
            }

        }
//        去掉导入表的重复数据,并且重复地址只取第一条
        ArrayList<InsideAddress> list = new ArrayList<>();
        ArrayList<String> addressDetailList = new ArrayList<>();
        for (int i = 0; i < insideAddresses.size(); i++) {
            InsideAddress insideAddress = insideAddresses.get(i);
            String addressDetail = insideAddress.getAddressDetail();
            if (!list.contains(insideAddress)&&!addressDetailList.contains(addressDetail)) {
                list.add(insideAddress);
                addressDetailList.add(addressDetail);
            }
        }

        this.saveBatch(list);

    }

    private void checkAddressUnique(InsideAddressDTO insideAddressDTO) {
        long count = baseMapper.selectCount(new LambdaQueryWrapper<InsideAddress>()
                .eq(InsideAddress::getAddressDetail, insideAddressDTO.getAddressDetail())
                .ne(ObjectUtil.isNotNull(insideAddressDTO.getId()), InsideAddress::getId, insideAddressDTO.getId()));
        if (count > 0) {
            throw new SqxException("地址详情不能重复");
        }
    }
}
