package com.ruoyi.tjfx.service.impl;

import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.tjfx.common.PageResponse;
import com.ruoyi.tjfx.entity.ShopCustomer;
import com.ruoyi.tjfx.entity.ShopCustomerExcelDTO;
import com.ruoyi.tjfx.mapper.ShopCustomerMapper;
import com.ruoyi.tjfx.service.ShopCustomerService;
import com.ruoyi.tjfx.util.ExcelUtil;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class ShopCustomerServiceImpl implements ShopCustomerService {
    @Autowired
    private ShopCustomerMapper shopCustomerMapper;

    @Override
    public List<ShopCustomer> listAll() {
        return shopCustomerMapper.selectList(null);
    }

    @Override
    public ShopCustomer getById(Long id) {
        return shopCustomerMapper.selectById(id);
    }

    @Override
    public void add(ShopCustomer shopCustomer) {
        shopCustomerMapper.insert(shopCustomer);
    }

    @Override
    public void update(Long id, ShopCustomer shopCustomer) {
        shopCustomer.setId(id);
        shopCustomerMapper.updateById(shopCustomer);
    }

    @Override
    public void delete(Long id) {
        shopCustomerMapper.deleteById(id);
    }

    @Override
    public void deleteBatch(List<Long> ids) {
        if (ids != null && !ids.isEmpty()) {
            shopCustomerMapper.deleteBatchIds(ids);
        }
    }

    @Override
    public PageResponse<ShopCustomer> getPage(Integer page, Integer pageSize, String shopName, String customerName) {
        // 创建分页对象
        Page<ShopCustomer> pageParam = new Page<>(page, pageSize);

        // 构建查询条件
        QueryWrapper<ShopCustomer> queryWrapper = new QueryWrapper<>();
        if (StringUtils.hasText(shopName)) {
            queryWrapper.like("shop_name", shopName);
        }
        if (StringUtils.hasText(customerName)) {
            queryWrapper.like("customer_name", customerName);
        }
        queryWrapper.orderByDesc("id");

        // 执行分页查询
        IPage<ShopCustomer> pageResult = shopCustomerMapper.selectPage(pageParam, queryWrapper);

        // 构建分页响应
        PageResponse.Pagination pagination = new PageResponse.Pagination(
                pageResult.getTotal(), page, pageSize);

        return new PageResponse<>(pageResult.getRecords(), pagination);
    }

    @Override
    public Map<String, Object> importExcel(MultipartFile file) {
        Map<String, Object> result = new HashMap<>();
        List<String> errors = new ArrayList<>();
        int successCount = 0;
        int totalRows = 0;

        try {
            // 1. 读取 Excel 数据（第一行为表头）
            List<ShopCustomerExcelDTO> excelDTOList  = EasyExcel.read(file.getInputStream())
                .head(ShopCustomerExcelDTO.class).headRowNumber(1).sheet().doReadSync();
            totalRows = excelDTOList.size();
            if (totalRows == 0) {
                result.put("total", 0);
                result.put("imported", 0);
                result.put("errors", 1);
                result.put("errorDetails", Collections.singletonList("Excel文件为空或格式不正确"));
                return result;
            }

            // 2. Excel内部去重、必填校验
            Set<String> duplicateCheck = new HashSet<>();
            List<ShopCustomer> validList = new ArrayList<>();

            for (int i = 0; i < excelDTOList.size(); i++) {
                ShopCustomerExcelDTO dto = excelDTOList.get(i);
                int rowIndex = i + 2; // Excel行号

                String shopName = dto.getShopName() != null ? dto.getShopName().trim() : "";
                String customerName = dto.getCustomerName() != null ? dto.getCustomerName().trim() : "";

                if (shopName.isEmpty() || customerName.isEmpty()) {
                    errors.add("第" + rowIndex + "行: 店铺名称和客户名称不能为空");
                    continue;
                }

                String key = shopName + "-" + customerName;
                if (!duplicateCheck.add(key)) {
                    errors.add("第" + rowIndex + "行: 店铺'" + shopName + "'与客户'" + customerName + "'的关联在Excel中重复");
                    continue;
                }

                ShopCustomer sc = new ShopCustomer();
                sc.setShopName(shopName);
                sc.setCustomerName(customerName);
                validList.add(sc);
            }

            // 3. 数据库去重
            if (!validList.isEmpty()) {
                List<String> dbKeys = validList.stream()
                    .map(sc -> sc.getShopName() + "-" + sc.getCustomerName())
                    .collect(Collectors.toList());

                QueryWrapper<ShopCustomer> queryWrapper = new QueryWrapper<>();
                queryWrapper.select("shop_name", "customer_name");
                queryWrapper.inSql("concat(shop_name,'-',customer_name)",
                    dbKeys.stream()
                        .map(k -> "'" + k.replace("'", "''") + "'")
                        .collect(Collectors.joining(",")));

                List<ShopCustomer> existList = shopCustomerMapper.selectList(queryWrapper);
                Set<String> existKeys = existList.stream()
                    .map(sc -> sc.getShopName() + "-" + sc.getCustomerName())
                    .collect(Collectors.toSet());

                // 过滤掉数据库中已存在的记录
                validList = validList.stream()
                    .filter(sc -> !existKeys.contains(sc.getShopName() + "-" + sc.getCustomerName()))
                    .collect(Collectors.toList());

                for (String k : dbKeys) {
                    if (existKeys.contains(k)) {
                        String[] parts = k.split("-", 2);
                        errors.add("店铺'" + parts[0] + "'与客户'" + parts[1] + "'的关联已存在于数据库中");
                    }
                }
            }

            // 4. 批量插入
            for (ShopCustomer sc : validList) {
                try {
                    shopCustomerMapper.insert(sc);
                    successCount++;
                } catch (Exception e) {
                    errors.add("插入失败: 店铺'" + sc.getShopName() + "', 客户'" + sc.getCustomerName() + "' - " + e.getMessage());
                }
            }
        } catch (Exception e) {
            errors.add("导入异常: " + e.getMessage());
        }

        result.put("total", totalRows);
        result.put("imported", successCount);
        result.put("errors", errors.size());
        result.put("errorDetails", errors.size() > 0 ? errors.subList(0, Math.min(10, errors.size())) : new ArrayList<>());
        return result;
    }


    @Override
    public void exportExcel(HttpServletResponse response) {
        try (Workbook workbook = new XSSFWorkbook()) {
            Sheet sheet = workbook.createSheet("店铺客户关联");

            String[] headers = {"店铺名称", "客户名称", "创建时间", "更新时间"};
            Row headerRow = sheet.createRow(0);
            for (int i = 0; i < headers.length; i++) {
                headerRow.createCell(i).setCellValue(headers[i]);
            }

            List<ShopCustomer> list = shopCustomerMapper.selectList(null);
            for (int i = 0; i < list.size(); i++) {
                ShopCustomer sc = list.get(i);
                Row row = sheet.createRow(i + 1);
                row.createCell(0).setCellValue(sc.getShopName() != null ? sc.getShopName() : "");
                row.createCell(1).setCellValue(sc.getCustomerName() != null ? sc.getCustomerName() : "");
                row.createCell(2).setCellValue(sc.getCreatedAt() != null ? sc.getCreatedAt().toString() : "");
                row.createCell(3).setCellValue(sc.getUpdatedAt() != null ? sc.getUpdatedAt().toString() : "");
            }

            for (int i = 0; i < headers.length; i++) {
                sheet.autoSizeColumn(i);
            }

            // 设置文件名
            String fileName = URLEncoder.encode("shop_customer.xlsx", "UTF-8").replaceAll("\\+", "%20");
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + fileName);

            workbook.write(response.getOutputStream());
            response.flushBuffer(); // 强制写出
        } catch (Exception e) {
            throw new RuntimeException("导出Excel失败: " + e.getMessage(), e);
        }
    }

}
