package com.ruoyi.ibs.task.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.common.config.OssFileProperties;
import com.ruoyi.common.core.domain.entity.CustInfoBusiness;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.common.utils.file.ImageUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.ibs.customerselect.mapper.CustInfoBusinessMapper;
import com.ruoyi.ibs.list.domain.CustInfoMerchant;
import com.ruoyi.ibs.list.domain.CustInfoRetail;
import com.ruoyi.ibs.list.mapper.*;
import com.ruoyi.ibs.task.domain.dto.TaskRecordDTO;
import com.ruoyi.ibs.task.domain.dto.TaskVisitCustAddressDTO;
import com.ruoyi.ibs.task.domain.entity.*;
import com.ruoyi.ibs.task.domain.vo.VisitRecordListVO;
import com.ruoyi.ibs.task.domain.vo.VisitRecordVO;
import com.ruoyi.ibs.task.mapper.*;
import com.ruoyi.ibs.task.service.TaskVisitRecordService;
import com.ruoyi.ibs.task.service.VisitFeedbackService;
import com.ruoyi.system.enums.OssFileEnum;
import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.system.service.OssFileService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ExecutorService;

/**
 * @Author 吴凯程
 * @Date 2025/6/17
 **/
@Service
@Slf4j
public class TaskVisitRecordServiceImpl implements TaskVisitRecordService {

    @Resource
    private TaskVisitRecordMapper taskVisitRecordMapper;

    @Resource
    private OssFileService ossFileService;

    @Resource
    private TaskVisitImageMapper taskVisitImageMapper;


    @Resource
    private TaskVisitSignMapper taskVisitSignMapper;

    @Resource
    private TaskVisitCustAddressMapper taskVisitCustAddressMapper;

    @Resource
    private VisitFeedbackService visitFeedbackService;

    @Resource
    private SysCampaignMapper sysCampaignMapper;

    @Resource
    private SysCampaignGroupCustomerMapper sysCampaignGroupCustomerMapper ;


    @Resource
    private ISysDeptService iSysDeptService ;
    @Resource
    private LowcodeVisstFeedbackModelMapper lowcodeVisstFeedbackModelMapper;


    @Resource
    private CustInfoBusinessMapper custInfoBusinessMapper;

    @Resource
    private CustInfoRetailMapper custInfoRetailMapper;

    @Resource
    private CustInfoMerchantMapper custInfoMerchantMapper;

    @Resource
    private ImportExportTaskMapper importExportTaskMapper;

    @Resource(name = "excelExportExecutor")
    private ExecutorService executorService;

    @Resource
    private OssFileProperties ossFileProperties;

    /**
     * @param signOutDTO
     * @return
     */


    /**
     * @param taskVisitCustAddressDTO
     * @return
     */
    @Override
    public String addCustAddress(TaskVisitCustAddressDTO taskVisitCustAddressDTO) {
        LambdaQueryWrapper<TaskVisitCustAddress> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(TaskVisitCustAddress::getCustId, taskVisitCustAddressDTO.getCustId())
                .eq(TaskVisitCustAddress::getUserName, SecurityUtils.getUsername());
        TaskVisitCustAddress taskVisitCustAddress = taskVisitCustAddressMapper.selectOne(queryWrapper);
        if (Objects.isNull(taskVisitCustAddress)){
            taskVisitCustAddress = new TaskVisitCustAddress();
            BeanUtils.copyProperties(taskVisitCustAddressDTO, taskVisitCustAddress);
            taskVisitCustAddress.setUserName(SecurityUtils.getUsername());
            taskVisitCustAddressMapper.insert(taskVisitCustAddress);
        }else {
            BeanUtils.copyProperties(taskVisitCustAddressDTO, taskVisitCustAddress);
            taskVisitCustAddressMapper.updateById(taskVisitCustAddress);
        }
        return "客户地址采集成功";
    }

    /**
     * @param recordId
     * @return
     */
    @Override
    public TaskVisitSign getCurrentSign(String recordId) {
        TaskVisitRecord taskVisitRecord = taskVisitRecordMapper.selectById(recordId);
        if (Objects.nonNull(taskVisitRecord) && Objects.nonNull(taskVisitRecord.getSignId())) {
            return taskVisitSignMapper.selectById(taskVisitRecord.getSignId());
        }
        return null;
    }

    /**
     * @param custId
     * @return
     */
    @Override
    public List<VisitRecordListVO> getVisitRecordList(String custId) {
        return taskVisitRecordMapper.getVisitRecordList(custId, SecurityUtils.getHeadId());
    }

    @Override
    public List<VisitRecordListVO> getVisitRecordListByCampaign(String custId,String campaignId) {
        return taskVisitRecordMapper.getVisitRecordListByCampaign(custId, SecurityUtils.getHeadId(),campaignId);
    }
    /**
     * @return
     */
    @Override
    public List<VisitRecordListVO> getVisitRecordListByUserName(TaskRecordDTO taskRecordDTO) {
        taskRecordDTO.setUserName(SecurityUtils.getUsername());
        taskRecordDTO.setPost(SecurityUtils.userRoleHeadOrBranch());
        taskRecordDTO.setDeptId(SecurityUtils.getDeptId());
        return taskVisitRecordMapper.getVisitRecordListByUserName(taskRecordDTO);
    }

    @Override
    @SneakyThrows
    public VisitRecordVO getVisitRecord(String recordId) {
        VisitRecordVO visitRecord = taskVisitRecordMapper.getVisitRecord(recordId);
        if (Objects.isNull(visitRecord)){
            throw new ServiceException("走访记录不存在");
        }
        LambdaQueryWrapper<TaskVisitSign> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(TaskVisitSign::getRecordId, recordId).orderByDesc(TaskVisitSign::getSignInTime);
        List<TaskVisitSign> taskVisitSigns = taskVisitSignMapper.selectList(queryWrapper);
        visitRecord.setSignList(taskVisitSigns);

        LambdaQueryWrapper<TaskVisitImage> imageQueryWrapper = new LambdaQueryWrapper<>();
        imageQueryWrapper.eq(TaskVisitImage::getRecordId, recordId);
        List<TaskVisitImage> taskVisitImages = taskVisitImageMapper.selectList(imageQueryWrapper);
        if (Objects.nonNull(taskVisitImages) && !taskVisitImages.isEmpty()) {
            List<String> imageList = new ArrayList<>();
            for (TaskVisitImage taskVisitImage : taskVisitImages) {
                MultipartFile fileFromOss = ossFileService.getFileFromOss(taskVisitImage.getFileId());
                imageList.add(ImageUtils.multiplePartFileToBase64(fileFromOss));
            }
            visitRecord.setImageList(imageList);
        }
        if (Objects.nonNull(visitRecord.getFeedbackId())){
            visitRecord.setFeedback(visitFeedbackService.getFeedback(visitRecord.getFeedbackType(), visitRecord.getFeedbackId()));
        }

        if("0".equalsIgnoreCase(visitRecord.getCustTyep())){
            CustInfoRetail custInfoRetail = custInfoRetailMapper.selectCustInfoRetailByCustId(visitRecord.getCustId());
            visitRecord.setIndustry(custInfoRetail.getBelongBusi());
        }
        if("1".equalsIgnoreCase(visitRecord.getCustTyep())){
            CustInfoMerchant custInfoMerchant = custInfoMerchantMapper.selectCustInfoMerchatByCustId(visitRecord.getCustId());
            visitRecord.setIndustry(custInfoMerchant.getIndustry());
        }
        if("2".equalsIgnoreCase(visitRecord.getCustTyep())){
            CustInfoBusiness custInfoBusiness = custInfoBusinessMapper.selectCustInfoBusinessByCustId(visitRecord.getCustId());
            visitRecord.setIndustry(custInfoBusiness.getIndustry());
        }

        return visitRecord;
    }

    /**
     * 走访记录导出
     */
    @Override
    public void export(HttpServletResponse response){
        List<VisitRecordListVO> visitRecordListAll = taskVisitRecordMapper.getVisitRecordListAll(SecurityUtils.getUsername(), String.valueOf(SecurityUtils.getDeptId()),SecurityUtils.userRole());

        // custType转换
        visitRecordListAll.forEach(record -> {
            if ("0".equals(record.getCustType())) {
                record.setCustType("个人");
            } else if ("1".equals(record.getCustType())) {
                record.setCustType("商户");
            } else if ("2".equals(record.getCustType())) {
                record.setCustType("企业");
            }
            if (Objects.nonNull(record.getFeedbackId())){
                JsonNode feedback = visitFeedbackService.getFeedback(record.getFeedbackType(), record.getFeedbackId());
                if (feedback != null) {
                    String chineseFeedback = convertFeedbackToChinese(feedback);
                    record.setFeedback(chineseFeedback);
                }
            }
        });
        try {
            EasyExcel.write(response.getOutputStream(), VisitRecordListVO.class)
                    .sheet("用户走访记录信息")
                    .doWrite(visitRecordListAll);
        } catch (Exception e) {
            throw new ServiceException("导出失败: " + e.getMessage());
        }
    }

    @Override
    public String exportAsync() {

        ImportExportTask task = new ImportExportTask();
        String taskId = IdUtils.randomUUID();
        task.setId(taskId);
        task.setStatus("0");
        Date now = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String formattedDate = sdf.format(now);
        task.setFileName(formattedDate + "走访记录信息导出");
        task.setUserName(SecurityUtils.getUsername());
        task.setCreateTime(now);
        importExportTaskMapper.insert(task);

        String username = SecurityUtils.getUsername();
        String deptId = String.valueOf(SecurityUtils.getDeptId());
        String userRole = SecurityUtils.userRole();

        executorService.submit(() -> doExport(taskId, username, deptId, userRole));

        return taskId;
    }

    private void doExport(String taskId, String username, String deptId, String userRole) {
        ImportExportTask task = importExportTaskMapper.selectById(taskId);
        File tempFile = null;
        try {

            tempFile = File.createTempFile("走访记录导出_"+ taskId + "-", ".xlsx");
            ExcelWriter excelWriter = EasyExcel.write(tempFile, VisitRecordListVO.class).build();
            WriteSheet writeSheet = EasyExcel.writerSheet("走访记录").build();
            int pageSize = 1000;
            int pageNum = 0;

            List<VisitRecordListVO> pageData;
            Map<String, Object> map = new HashMap<>();
            do {
                map.put("username", username);
                map.put("deptId", deptId);
                map.put("role", userRole);
                map.put("offset", pageNum * pageSize);
                map.put("pageSize", pageSize);
                //查询数据
                pageData = taskVisitRecordMapper.getVisitRecordListByPage(map);

                // custType转换
                pageData.forEach(record -> {
                    if ("0".equals(record.getCustType())) {
                        record.setCustType("个人");
                    } else if ("1".equals(record.getCustType())) {
                        record.setCustType("商户");
                    } else if ("2".equals(record.getCustType())) {
                        record.setCustType("企业");
                    }
                    if (Objects.nonNull(record.getFeedbackId())){
                        JsonNode feedback = visitFeedbackService.getFeedback(record.getFeedbackType(), record.getFeedbackId());
                        if (feedback != null) {
                            String chineseFeedback = convertFeedbackToChinese(feedback);
                            record.setFeedback(chineseFeedback);
                        }
                    }
                });
                if (!pageData.isEmpty()){
                    excelWriter.write(pageData, writeSheet);
                }
                pageNum++;

            }while (pageData.size() == pageSize);
            excelWriter.finish();

            //上传
            String ossUUId = ossFileService.uploadFileToOss(OssFileEnum.VISIT_RECORD, tempFile, "走访记录导出_" + taskId + ".xlsx", username);

            //更新任务状态
            task.setStatus("1");
            task.setFileUrl(ossUUId);
            task.setFinishTime(new Date());
            importExportTaskMapper.updateById(task);

        }catch (Exception e){
            task.setStatus("2");
            task.setFinishTime(new Date());
            task.setErrorMsg(e.getMessage());
            importExportTaskMapper.updateById(task);
        }finally {
            //删除临时文件
            if (Objects.nonNull(tempFile)){
                boolean deleted = tempFile.delete();
                if (!deleted){
                    log.error("临时文件删除失败" + tempFile.getAbsolutePath());
                }
            }
        }
    }

    /**
     * 下载走访记录文件
     * @param fileUrl
     * @param response
     */
    @Override
    public void downloadFileByUUid(String fileUrl, HttpServletResponse response) {
        try {
            // 使用 OssFileService 获取 MultipartFile
            MultipartFile file = ossFileService.getFileFromOss(fileUrl);

            if (file == null || file.isEmpty()) {
                response.setStatus(HttpServletResponse.SC_NOT_FOUND);
                response.getWriter().write("文件不存在");
                return;
            }

            // 设置响应头
            response.setContentType(file.getContentType());
            response.setHeader("Content-Disposition", "attachment; filename=\"" + file.getOriginalFilename() + "\"");

            // 写入响应流
            // 改为以下代码：
            try (InputStream inputStream = file.getInputStream();
                 OutputStream outputStream = response.getOutputStream()) {
                byte[] buffer = new byte[1024];
                int len;
                while ((len = inputStream.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, len);
                }
                outputStream.flush();
            }
        } catch (Exception e) {
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            try {
                response.getWriter().write("文件下载失败: " + e.getMessage());
            } catch (Exception ex) {
                throw new RuntimeException(ex);
            }
        }
    }

    /**
     * 将feedback JSON中的字段名转换为中文
     */
    private String convertFeedbackToChinese(JsonNode feedback) {
        Map<String, String> fieldMapping = new HashMap<>();
        fieldMapping.put("clientSuggestion", "客户反馈意见");
        fieldMapping.put("intendProduct", "意向产品");
        fieldMapping.put("otherIntend", "其他意向");
        fieldMapping.put("statusFlag", "是否经营");
        fieldMapping.put("addressConsist", "地址是否一致");
        fieldMapping.put("address", "地址");
        fieldMapping.put("scopeConsist", "经营范围是否一致");
        fieldMapping.put("scope", "经营范围");
        fieldMapping.put("relatePerson", "关联人");
        // 可以继续添加更多字段映射
        Map<String, Object> resultMap = new LinkedHashMap<>();
        Iterator<Map.Entry<String, JsonNode>> fields = feedback.fields();
        while (fields.hasNext()) {
            Map.Entry<String, JsonNode> field = fields.next();
            String fieldName = field.getKey();
            JsonNode fieldValue = field.getValue();
            // 获取中文字段名
            String chineseFieldName = fieldMapping.getOrDefault(fieldName, fieldName);
            // 处理值（如果需要的话，也可以对值进行转换）
            if (fieldValue.isArray()) {
                List<String> arrayValues = new ArrayList<>();
                for (JsonNode node : fieldValue) {
                    arrayValues.add(node.asText());
                }
                resultMap.put(chineseFieldName, arrayValues);
            } else {
                resultMap.put(chineseFieldName, fieldValue.asText());
            }
        }
        // 转换为JSON字符串
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            return objectMapper.writeValueAsString(resultMap);
        } catch (Exception e) {
            return feedback.toString();
        }
    }

}
