package org.xyzh.crontab.service.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.xyzh.api.crontab.DataCollectionItemService;
import org.xyzh.api.news.resource.ResourceService;
import org.xyzh.common.core.domain.ResultDomain;
import org.xyzh.common.core.page.PageDomain;
import org.xyzh.common.core.page.PageParam;
import org.xyzh.common.dto.crontab.TbDataCollectionItem;
import org.xyzh.common.dto.resource.TbResource;
import org.xyzh.common.utils.IDUtils;
import org.xyzh.common.vo.DataCollectionItemVO;
import org.xyzh.common.vo.ResourceVO;
import org.xyzh.crontab.mapper.DataCollectionItemMapper;
import org.xyzh.crontab.mapper.CrontabLogMapper;
import org.xyzh.crontab.mapper.CrontabTaskMapper;
import org.xyzh.common.dto.crontab.TbCrontabLog;
import org.xyzh.common.dto.crontab.TbCrontabTask;
import org.xyzh.system.utils.LoginUtil;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @description 数据采集项服务实现类
 * @filename DataCollectionItemServiceImpl.java
 * @author yslg
 * @copyright xyzh
 * @since 2025-11-08
 */
@Service
public class DataCollectionItemServiceImpl implements DataCollectionItemService {

    private static final Logger logger = LoggerFactory.getLogger(DataCollectionItemServiceImpl.class);

    @Autowired
    private DataCollectionItemMapper itemMapper;

    @Autowired
    private CrontabTaskMapper taskMapper;

    @Autowired
    private CrontabLogMapper logMapper;

    @Autowired
    private ResourceService resourceService;

    private final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDomain<TbDataCollectionItem> createItem(TbDataCollectionItem item) {
        ResultDomain<TbDataCollectionItem> resultDomain = new ResultDomain<>();
        try {
            // 检查URL是否已存在（去重）
            if (item.getSourceUrl() != null && !item.getSourceUrl().isEmpty()) {
                TbDataCollectionItem existing = itemMapper.selectBySourceUrl(item.getSourceUrl());
                if (existing != null) {
                    resultDomain.fail("该文章已存在，URL: " + item.getSourceUrl());
                    return resultDomain;
                }
            }

            // 生成ID
            item.setID(IDUtils.generateID());
            item.setCreateTime(new Date());
            item.setDeleted(false);

            // 默认值
            if (item.getStatus() == null) {
                item.setStatus(0); // 默认未处理
            }
            if (item.getCrawlTime() == null) {
                item.setCrawlTime(new Date());
            }

            int result = itemMapper.insert(item);
            if (result > 0) {
                logger.info("创建采集项成功: {}", item.getTitle());
                resultDomain.success("创建采集项成功", item);
            } else {
                resultDomain.fail("创建采集项失败");
            }
        } catch (Exception e) {
            logger.error("创建采集项异常: ", e);
            resultDomain.fail("创建采集项异常: " + e.getMessage());
        }
        return resultDomain;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDomain<TbDataCollectionItem> batchCreateItems(List<TbDataCollectionItem> itemList) {
        ResultDomain<TbDataCollectionItem> resultDomain = new ResultDomain<>();
        try {
            if (itemList == null || itemList.isEmpty()) {
                resultDomain.fail("采集项列表为空");
                return resultDomain;
            }

            int successCount = 0;
            List<TbDataCollectionItem> createdItems = new ArrayList<>();
            // 改为逐条创建，避免单条失败导致整批回滚
            for (TbDataCollectionItem it : itemList) {
                ResultDomain<TbDataCollectionItem> createResult = createItem(it);
                if (createResult.isSuccess()) {
                    successCount++;
                    if (createResult.getData() != null) {
                        createdItems.add(createResult.getData());
                    }
                }
            }
            String logId = itemList.get(0).getLogId();
            TbCrontabLog log = new TbCrontabLog();
            log.setID(logId);
            log.setExecuteStatus(1);
            log.setExecuteMessage("爬取成功，共" + itemList.size() + "条，新增" + successCount + "条");
            int i = logMapper.updateLog(log);

            logger.info("批量创建采集项成功，共{}条，成功{}条", itemList.size(), successCount);
            resultDomain.success("批量创建采集项成功", createdItems);
        } catch (Exception e) {
            logger.error("批量创建采集项异常: ", e);
            resultDomain.fail("批量创建采集项异常: " + e.getMessage());
        }
        return resultDomain;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDomain<TbDataCollectionItem> updateItem(TbDataCollectionItem item) {
        ResultDomain<TbDataCollectionItem> resultDomain = new ResultDomain<>();
        try {
            if (item.getID() == null) {
                resultDomain.fail("采集项ID不能为空");
                return resultDomain;
            }

            item.setUpdateTime(new Date());
            int result = itemMapper.updateById(item);
            
            if (result > 0) {
                logger.info("更新采集项成功: {}", item.getID());
                resultDomain.success("更新采集项成功", item);
            } else {
                resultDomain.fail("更新采集项失败");
            }
        } catch (Exception e) {
            logger.error("更新采集项异常: ", e);
            resultDomain.fail("更新采集项异常: " + e.getMessage());
        }
        return resultDomain;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDomain<TbDataCollectionItem> deleteItem(String itemId) {
        ResultDomain<TbDataCollectionItem> resultDomain = new ResultDomain<>();
        try {
            if (itemId == null || itemId.isEmpty()) {
                resultDomain.fail("采集项ID不能为空");
                return resultDomain;
            }

            int result = itemMapper.deleteById(itemId);
            if (result > 0) {
                logger.info("删除采集项成功，ID: {}", itemId);
                resultDomain.success("删除采集项成功", (TbDataCollectionItem) null);
            } else {
                resultDomain.fail("删除采集项失败");
            }
        } catch (Exception e) {
            logger.error("删除采集项异常: ", e);
            resultDomain.fail("删除采集项异常: " + e.getMessage());
        }
        return resultDomain;
    }

    @Override
    public ResultDomain<DataCollectionItemVO> getItemById(String itemId) {
        ResultDomain<DataCollectionItemVO> resultDomain = new ResultDomain<>();
        try {
            if (itemId == null || itemId.isEmpty()) {
                resultDomain.fail("采集项ID不能为空");
                return resultDomain;
            }

            DataCollectionItemVO vo = itemMapper.selectVOById(itemId);
            if (vo != null) {
                resultDomain.success("查询成功", vo);
            } else {
                resultDomain.fail("采集项不存在");
            }
        } catch (Exception e) {
            logger.error("查询采集项异常: ", e);
            resultDomain.fail("查询采集项异常: " + e.getMessage());
        }
        return resultDomain;
    }

    @Override
    public ResultDomain<DataCollectionItemVO> getItemList(TbDataCollectionItem filter) {
        ResultDomain<DataCollectionItemVO> resultDomain = new ResultDomain<>();
        try {
            if (filter == null) {
                filter = new TbDataCollectionItem();
            }
            filter.setDeleted(false);

            List<DataCollectionItemVO> voList = itemMapper.selectVOList(filter);


            resultDomain.success("查询成功", voList);
        } catch (Exception e) {
            logger.error("查询采集项列表异常: ", e);
            resultDomain.fail("查询采集项列表异常: " + e.getMessage());
        }
        return resultDomain;
    }

    @Override
    public ResultDomain<DataCollectionItemVO> getItemPage(TbDataCollectionItem filter, PageParam pageParam) {
        ResultDomain<DataCollectionItemVO> resultDomain = new ResultDomain<>();
        try {
            if (filter == null) {
                filter = new TbDataCollectionItem();
            }
            filter.setDeleted(false);

            if (pageParam == null) {
                pageParam = new PageParam();
            }

            List<DataCollectionItemVO> voList = itemMapper.selectVOPage(filter, pageParam);

            long total = itemMapper.countItems(filter);

            PageDomain<DataCollectionItemVO> pageDomain = new PageDomain<>();
            pageDomain.setDataList(voList);
            pageParam.setTotalElements(total);
            pageParam.setTotalPages((int) Math.ceil((double) total / pageParam.getPageSize()));
            pageDomain.setPageParam(pageParam);

            resultDomain.success("查询成功", pageDomain);
        } catch (Exception e) {
            logger.error("分页查询采集项异常: ", e);
            resultDomain.fail("分页查询采集项异常: " + e.getMessage());
        }
        return resultDomain;
    }

    @Override
    public ResultDomain<DataCollectionItemVO> getItemsByTaskId(String taskId) {
        ResultDomain<DataCollectionItemVO> resultDomain = new ResultDomain<>();
        try {
            if (taskId == null || taskId.isEmpty()) {
                resultDomain.fail("任务ID不能为空");
                return resultDomain;
            }

            List<DataCollectionItemVO> voList = itemMapper.selectVOByTaskId(taskId);


            resultDomain.success("查询成功", voList);
        } catch (Exception e) {
            logger.error("根据任务ID查询采集项异常: ", e);
            resultDomain.fail("根据任务ID查询采集项异常: " + e.getMessage());
        }
        return resultDomain;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDomain<String> convertToResource(String itemId, String tagId) {
        ResultDomain<String> resultDomain = new ResultDomain<>();
        try {
            if (itemId == null || itemId.isEmpty()) {
                resultDomain.fail("采集项ID不能为空");
                return resultDomain;
            }
            if (tagId == null || tagId.isEmpty()) {
                resultDomain.fail("标签ID不能为空");
                return resultDomain;
            }

            // 查询采集项
            TbDataCollectionItem item = itemMapper.selectById(itemId);
            if (item == null) {
                resultDomain.fail("采集项不存在");
                return resultDomain;
            }

            if (item.getStatus() == 1) {
                resultDomain.fail("该采集项已转换为资源");
                return resultDomain;
            }

            // 创建资源
            TbResource resource = new TbResource();
            resource.setResourceID(IDUtils.generateID());
            resource.setTitle(item.getTitle());
            resource.setContent(item.getContent());
            resource.setSummary(item.getSummary());
            resource.setCoverImage(item.getCoverImage());
            resource.setTagID(tagId);
            resource.setAuthor(item.getAuthor());
            resource.setSource(item.getSource());
            resource.setSourceUrl(item.getSourceUrl());
            resource.setPublishTime(item.getPublishTime() != null ? item.getPublishTime() : new Date());
            resource.setStatus(1); // 已发布
            resource.setViewCount(0);
            resource.setLikeCount(0);
            resource.setCollectCount(0);
            resource.setIsRecommend(false);
            resource.setIsBanner(false);
            resource.setCreateTime(new Date());
            resource.setDeleted(false);

            ResourceVO resourceVO = new ResourceVO();
            resourceVO.setResource(resource);

            ResultDomain<ResourceVO> createResult = resourceService.createResource(resourceVO);
            if (!createResult.isSuccess()) {
                resultDomain.fail("转换为资源失败: " + createResult.getMessage());
                return resultDomain;
            }

            // 更新采集项状态
            item.setStatus(1); // 已转换为资源
            item.setResourceId(resource.getResourceID());
            item.setProcessTime(new Date());
            item.setProcessor(LoginUtil.getCurrentUserId());
            itemMapper.updateById(item);

            logger.info("采集项转换为资源成功，采集项ID: {}, 资源ID: {}", itemId, resource.getResourceID());
            resultDomain.success("转换为资源成功", resource.getResourceID());
        } catch (Exception e) {
            logger.error("转换为资源异常: ", e);
            resultDomain.fail("转换为资源异常: " + e.getMessage());
        }
        return resultDomain;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDomain<Integer> batchConvertToResource(List<String> itemIds, String tagId) {
        ResultDomain<Integer> resultDomain = new ResultDomain<>();
        try {
            if (itemIds == null || itemIds.isEmpty()) {
                resultDomain.fail("采集项ID列表为空");
                return resultDomain;
            }
            if (tagId == null || tagId.isEmpty()) {
                resultDomain.fail("标签ID不能为空");
                return resultDomain;
            }

            int successCount = 0;
            for (String itemId : itemIds) {
                ResultDomain<String> convertResult = convertToResource(itemId, tagId);
                if (convertResult.isSuccess()) {
                    successCount++;
                }
            }

            logger.info("批量转换为资源完成，共{}条，成功{}条", itemIds.size(), successCount);
            resultDomain.success("批量转换为资源完成", successCount);
        } catch (Exception e) {
            logger.error("批量转换为资源异常: ", e);
            resultDomain.fail("批量转换为资源异常: " + e.getMessage());
        }
        return resultDomain;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDomain<TbDataCollectionItem> ignoreItem(String itemId) {
        ResultDomain<TbDataCollectionItem> resultDomain = new ResultDomain<>();
        try {
            if (itemId == null || itemId.isEmpty()) {
                resultDomain.fail("采集项ID不能为空");
                return resultDomain;
            }

            TbDataCollectionItem item = itemMapper.selectById(itemId);
            if (item == null) {
                resultDomain.fail("采集项不存在");
                return resultDomain;
            }

            item.setStatus(2); // 已忽略
            item.setProcessTime(new Date());
            item.setProcessor(LoginUtil.getCurrentUserId());
            itemMapper.updateById(item);

            logger.info("忽略采集项成功，ID: {}", itemId);
            resultDomain.success("忽略采集项成功", item);
        } catch (Exception e) {
            logger.error("忽略采集项异常: ", e);
            resultDomain.fail("忽略采集项异常: " + e.getMessage());
        }
        return resultDomain;
    }

    @Override
    public ResultDomain<Long> countByStatus(String taskId, Integer status) {
        ResultDomain<Long> resultDomain = new ResultDomain<>();
        try {
            long count = itemMapper.countByStatus(taskId, status);
            resultDomain.success("统计成功", count);
        } catch (Exception e) {
            logger.error("统计采集项数量异常: ", e);
            resultDomain.fail("统计采集项数量异常: " + e.getMessage());
        }
        return resultDomain;
    }

    @Override
    public ResultDomain<String> updateItemStatus(String itemId, int status) {
        ResultDomain<String> resultDomain = new ResultDomain<>();
        try {
            int result = itemMapper.updateItemStatus(itemId, status);
            if (result > 0) {
                resultDomain.success("更新采集项状态成功", itemId);
            } else {
                resultDomain.fail("更新采集项状态失败");
            }
        } catch (Exception e) {
            logger.error("更新采集项状态异常: ", e);
            resultDomain.fail("更新采集项状态异常: " + e.getMessage());
        }
        return resultDomain;
    }
}

