package com.aegis.emergency.event.service.impl;

import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.aegis.common.exception.ServiceException;
import com.aegis.common.utils.SecurityUtils;
import com.aegis.common.utils.StringUtils;
import com.aegis.common.utils.uuid.Seq;
import com.aegis.emergency.event.constant.EventStatus;
import com.aegis.emergency.event.constant.EventAction;
import com.aegis.emergency.event.domain.Event;
import com.aegis.emergency.event.mapper.EventMapper;
import com.aegis.emergency.event.service.IEventService;
import com.aegis.emergency.event.service.IEventLogService;
import com.aegis.emergency.report.domain.ProvinceReport;
import com.aegis.emergency.report.service.IProvinceReportService;

/**
 * 事件Service业务层处理
 * 
 * @author aegis
 */
@Service
public class EventServiceImpl extends ServiceImpl<EventMapper, Event> implements IEventService {

    @Autowired
    private IEventLogService eventLogService;

    @Autowired
    private IProvinceReportService provinceReportService;

    @Override
    public List<Event> listByCondition(Event condition) {
        LambdaQueryWrapper<Event> wrapper = new LambdaQueryWrapper<>();
        if (condition != null) {
            if (StringUtils.isNotEmpty(condition.getEventNo())) {
                wrapper.eq(Event::getEventNo, condition.getEventNo());
            }
            if (StringUtils.isNotEmpty(condition.getType())) {
                wrapper.eq(Event::getType, condition.getType());
            }
            if (StringUtils.isNotEmpty(condition.getLevel())) {
                wrapper.eq(Event::getLevel, condition.getLevel());
            }
            if (StringUtils.isNotEmpty(condition.getStatus())) {
                wrapper.eq(Event::getStatus, condition.getStatus());
            }
            // 排除指定状态（用于查询时排除已完成、归档等状态）
            if (condition.getExcludeStatuses() != null && !condition.getExcludeStatuses().isEmpty()) {
                wrapper.notIn(Event::getStatus, condition.getExcludeStatuses());
            }
            // 批量查询事件ID（IN子句）
            if (condition.getIds() != null && !condition.getIds().isEmpty()) {
                wrapper.in(Event::getId, condition.getIds());
            }
            if (StringUtils.isNotEmpty(condition.getSource())) {
                wrapper.eq(Event::getSource, condition.getSource());
            }
            // 发生时间范围查询
            if (condition.getBeginOccurredAt() != null && condition.getEndOccurredAt() != null) {
                wrapper.between(Event::getOccurredAt, condition.getBeginOccurredAt(), condition.getEndOccurredAt());
            } else if (condition.getBeginOccurredAt() != null) {
                wrapper.ge(Event::getOccurredAt, condition.getBeginOccurredAt());
            } else if (condition.getEndOccurredAt() != null) {
                wrapper.le(Event::getOccurredAt, condition.getEndOccurredAt());
            }
        }
        wrapper.eq(Event::getDelFlag, "0"); // 只查询未删除的记录
        wrapper.orderByDesc(Event::getOccurredAt); // 按发生时间倒序
        List<Event> events = list(wrapper);
        
        // 如果查询条件包含上报状态或上报时间，需要先过滤
        if (condition != null && (StringUtils.isNotBlank(condition.getProvinceReportStatusFilter()) 
                || condition.getBeginProvinceReportTime() != null 
                || condition.getEndProvinceReportTime() != null)) {
            events = filterAndEnrichEventsWithReportStatus(events, condition);
        } else {
            // 只填充上报状态，不过滤
            enrichEventsWithReportStatus(events);
        }
        
        return events;
    }

    @Override
    public Event getByEventNo(String eventNo) {
        if (StringUtils.isEmpty(eventNo)) {
            throw new ServiceException("事件编号不能为空");
        }
        LambdaQueryWrapper<Event> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Event::getEventNo, eventNo);
        wrapper.eq(Event::getDelFlag, "0");
        return getOne(wrapper);
    }

    @Override
    @Transactional
    public boolean startProcessing(Long id) {
        if (id == null) {
            throw new ServiceException("事件ID不能为空");
        }
        
        Event event = getById(id);
        if (event == null || "2".equals(event.getDelFlag())) {
            throw new ServiceException("事件不存在或已删除");
        }
        
        // 业务规则：只能从pending状态开始处理
        if (!EventStatus.PENDING.getCode().equals(event.getStatus())) {
            throw new ServiceException("只能开始处理待处理状态的事件，当前状态：" + event.getStatus());
        }
        
        event.setStatus(EventStatus.PROCESSING.getCode());
        String operator = SecurityUtils.getUsername();
        event.setUpdateBy(operator);
        event.setUpdateTime(new Date());
        
        boolean updated = super.updateById(event);
        if (updated) {
            eventLogService.recordLog(id, EventAction.STATUS_CHANGE.getCode(), 
                "状态变更：pending → processing");
        }
        return updated;
    }

    @Override
    @Transactional
    public boolean completeEvent(Long id) {
        if (id == null) {
            throw new ServiceException("事件ID不能为空");
        }
        
        Event event = getById(id);
        if (event == null || "2".equals(event.getDelFlag())) {
            throw new ServiceException("事件不存在或已删除");
        }
        
        // 业务规则：只能完成处理中状态的事件
        if (!EventStatus.PROCESSING.getCode().equals(event.getStatus())) {
            throw new ServiceException("只能完成处理中状态的事件，当前状态：" + event.getStatus());
        }
        
        event.setStatus(EventStatus.COMPLETED.getCode());
        String operator = SecurityUtils.getUsername();
        event.setUpdateBy(operator);
        event.setUpdateTime(new Date());
        
        boolean updated = super.updateById(event);
        if (updated) {
            eventLogService.recordLog(id, EventAction.STATUS_CHANGE.getCode(), 
                "状态变更：processing → completed");
        }
        return updated;
    }

    @Override
    @Transactional
    public boolean archiveEvent(Long id) {
        if (id == null) {
            throw new ServiceException("事件ID不能为空");
        }
        
        Event event = getById(id);
        if (event == null || "2".equals(event.getDelFlag())) {
            throw new ServiceException("事件不存在或已删除");
        }
        
        // 业务规则：只能归档已完成状态的事件
        if (!EventStatus.COMPLETED.getCode().equals(event.getStatus())) {
            throw new ServiceException("只能归档已完成状态的事件，当前状态：" + event.getStatus());
        }
        
        event.setStatus(EventStatus.ARCHIVED.getCode());
        String operator = SecurityUtils.getUsername();
        event.setUpdateBy(operator);
        event.setUpdateTime(new Date());
        
        boolean updated = super.updateById(event);
        if (updated) {
            eventLogService.recordLog(id, EventAction.STATUS_CHANGE.getCode(), 
                "状态变更：completed → archived");
        }
        return updated;
    }

    @Override
    @Transactional
    public boolean save(Event event) {
        if (event == null) {
            throw new ServiceException("事件信息不能为空");
        }
        
        // 生成事件编号（如果未提供）
        if (StringUtils.isEmpty(event.getEventNo())) {
            event.setEventNo(generateEventNo());
        } else {
            // 检查事件编号是否已存在
            Event existing = getByEventNo(event.getEventNo());
            if (existing != null) {
                throw new ServiceException("事件编号已存在：" + event.getEventNo());
            }
        }
        
        String operator = SecurityUtils.getUsername();
        event.setCreateBy(operator);
        event.setCreateTime(new Date());
        event.setUpdateBy(operator);
        event.setUpdateTime(new Date());
        
        // 设置默认值
        if (StringUtils.isEmpty(event.getStatus())) {
            event.setStatus(EventStatus.DRAFT.getCode());
        }
        if (StringUtils.isEmpty(event.getDelFlag())) {
            event.setDelFlag("0");
        }
        
        boolean saved = super.save(event);
        if (saved) {
            eventLogService.recordLog(event.getId(), EventAction.EVENT_CREATED.getCode(), event);
        }
        return saved;
    }

    @Override
    @Transactional
    public boolean updateById(Event event) {
        boolean updated = updateEventSilently(event);
        if (updated) {
            eventLogService.recordLog(event.getId(), EventAction.EVENT_UPDATED.getCode(), event);
        }
        return updated;
    }

    @Override
    @Transactional
    public boolean removeById(Serializable id) {
        if (id == null) {
            throw new ServiceException("事件ID不能为空");
        }
        
        Event event = getById(id);
        if (event == null || "2".equals(event.getDelFlag())) {
            throw new ServiceException("事件不存在或已删除");
        }
        
        // 业务规则：只能删除草稿状态的事件
        if (!EventStatus.DRAFT.getCode().equals(event.getStatus())) {
            throw new ServiceException("只能删除草稿状态的事件，当前状态：" + event.getStatus());
        }
        
        // 逻辑删除事件
        event.setDelFlag("2");
        String operator = SecurityUtils.getUsername();
        event.setUpdateBy(operator);
        event.setUpdateTime(new Date());
        
        boolean removed = super.updateById(event);
        if (removed) {
            eventLogService.recordLog(event.getId(), EventAction.EVENT_DELETED.getCode(), event);
        }
        return removed;
    }

    /**
     * 生成事件编号（基于日期+序列）
     * 格式：EVENT + yyyyMMdd + 序列号
     * 
     * @return 事件编号
     */
    private String generateEventNo() {
        // 使用日期格式 + 序列号
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String dateStr = sdf.format(new Date());
        // Seq.getId() 返回格式：yyMMddHHmmss + 机器标识 + 3位序列，我们只取最后3位序列号
        String seqId = Seq.getId();
        String seq = seqId.substring(seqId.length() - 3); // 取最后3位作为序列号
        return "EVENT" + dateStr + seq;
    }

    /**
     * 更新事件（不记录日志，供内部方法使用）
     * 
     * @param event 事件信息
     * @return 是否更新成功
     */
    private boolean updateEventSilently(Event event) {
        if (event == null || event.getId() == null) {
            throw new ServiceException("事件信息或ID不能为空");
        }
        
        // 检查事件是否存在
        Event existingEvent = getById(event.getId());
        if (existingEvent == null || "2".equals(existingEvent.getDelFlag())) {
            throw new ServiceException("事件不存在或已删除");
        }
        
        // 业务规则：归档后不可编辑
        if (EventStatus.ARCHIVED.getCode().equals(existingEvent.getStatus())) {
            throw new ServiceException("事件已归档，不可编辑");
        }
        
        // 如果修改了事件编号，检查是否重复
        if (StringUtils.isNotEmpty(event.getEventNo()) 
                && !event.getEventNo().equals(existingEvent.getEventNo())) {
            Event duplicate = getByEventNo(event.getEventNo());
            if (duplicate != null && !duplicate.getId().equals(event.getId())) {
                throw new ServiceException("事件编号已存在：" + event.getEventNo());
            }
        }
        
        String operator = SecurityUtils.getUsername();
        event.setUpdateBy(operator);
        event.setUpdateTime(new Date());
        
        return super.updateById(event);
    }

    @Override
    @Transactional
    public boolean reportEvent(Long id, String reportContent) {
        if (id == null) {
            throw new ServiceException("事件ID不能为空");
        }

        Event event = getById(id);
        if (event == null || "2".equals(event.getDelFlag())) {
            throw new ServiceException("事件不存在或已删除");
        }

        // TODO: 集成上级政府部门上报接口
        // 1. 调用上级政府部门的API接口上报事件信息
        // 2. 处理上报结果（成功/失败）
        // 3. 如果上报失败，记录失败原因
        // 示例：
        // try {
        //     GovernmentReportService.report(event, reportContent);
        // } catch (Exception e) {
        //     throw new ServiceException("上报失败：" + e.getMessage());
        // }

        // 记录上报日志
        Map<String, Object> payload = new HashMap<>();
        payload.put("reportContent", reportContent);
        payload.put("eventNo", event.getEventNo());
        payload.put("eventTitle", event.getTitle());
        eventLogService.recordLog(id, EventAction.REPORT.getCode(), payload);

        return true;
    }

    @Override
    @Transactional
    public boolean followUpReport(Long id, String reportContent) {
        if (id == null) {
            throw new ServiceException("事件ID不能为空");
        }

        Event event = getById(id);
        if (event == null || "2".equals(event.getDelFlag())) {
            throw new ServiceException("事件不存在或已删除");
        }

        // TODO: 集成上级政府部门续报接口
        // 1. 调用上级政府部门的API接口续报事件信息
        // 2. 处理续报结果（成功/失败）
        // 3. 如果续报失败，记录失败原因
        // 示例：
        // try {
        //     GovernmentReportService.followUpReport(event, reportContent);
        // } catch (Exception e) {
        //     throw new ServiceException("续报失败：" + e.getMessage());
        // }

        // 记录续报日志
        Map<String, Object> payload = new HashMap<>();
        payload.put("reportContent", reportContent);
        payload.put("eventNo", event.getEventNo());
        payload.put("eventTitle", event.getTitle());
        eventLogService.recordLog(id, EventAction.FOLLOW_UP_REPORT.getCode(), payload);

        return true;
    }

    @Override
    @Transactional
    public boolean markImportant(Long id, boolean important) {
        if (id == null) {
            throw new ServiceException("事件ID不能为空");
        }

        Event event = getById(id);
        if (event == null || "2".equals(event.getDelFlag())) {
            throw new ServiceException("事件不存在或已删除");
        }

        Integer targetFlag = important ? 1 : 0;
        Integer currentFlag = event.getImportantFlag();
        if (currentFlag != null && currentFlag.equals(targetFlag)) {
            return true;
        }

        Date now = new Date();
        String operator = SecurityUtils.getUsername();
        event.setImportantFlag(targetFlag);
        event.setImportantBy(important ? operator : null);
        event.setImportantTime(important ? now : null);
        event.setUpdateBy(operator);
        event.setUpdateTime(now);

        boolean updated = super.updateById(event);
        if (updated) {
            Map<String, Object> payload = new HashMap<>();
            payload.put("important", important);
            payload.put("operator", operator);
            payload.put("time", now);
            eventLogService.recordLog(
                id,
                important ? EventAction.EVENT_PINNED.getCode() : EventAction.EVENT_UNPINNED.getCode(),
                payload
            );
        }
        return updated;
    }

    @Override
    public Event getById(Serializable id) {
        if (id == null) {
            throw new ServiceException("事件ID不能为空");
        }
        Event event = super.getById(id);
        if (event != null && "2".equals(event.getDelFlag())) {
            return null; // 已删除的记录返回 null
        }
        if (event != null) {
            enrichEventsWithReportStatus(java.util.Collections.singletonList(event));
        }
        return event;
    }

    /**
     * 过滤并填充事件的上报状态信息（带过滤条件）
     */
    private List<Event> filterAndEnrichEventsWithReportStatus(List<Event> events, Event condition) {
        if (events == null || events.isEmpty()) {
            return events;
        }
        
        // 先填充上报状态
        enrichEventsWithReportStatus(events);
        
        // 根据上报状态和时间过滤
        return events.stream()
            .filter(event -> {
                // 过滤上报状态
                if (StringUtils.isNotBlank(condition.getProvinceReportStatusFilter())) {
                    String status = event.getProvinceReportStatus();
                    if (!condition.getProvinceReportStatusFilter().equals(status)) {
                        // 如果查询条件是"pending"但事件没有上报记录，也应该显示
                        if (!"pending".equals(condition.getProvinceReportStatusFilter()) 
                            || status != null) {
                            return false;
                        }
                    }
                }
                
                // 过滤上报时间范围
                if (condition.getBeginProvinceReportTime() != null 
                    || condition.getEndProvinceReportTime() != null) {
                    Date reportTime = event.getProvinceReportTime();
                    if (reportTime == null) {
                        return false; // 没有上报记录，不满足时间范围
                    }
                    if (condition.getBeginProvinceReportTime() != null 
                        && reportTime.before(condition.getBeginProvinceReportTime())) {
                        return false;
                    }
                    if (condition.getEndProvinceReportTime() != null 
                        && reportTime.after(condition.getEndProvinceReportTime())) {
                        return false;
                    }
                }
                
                return true;
            })
            .collect(java.util.stream.Collectors.toList());
    }

    /**
     * 关联查询，填充事件的上报状态信息
     */
    private void enrichEventsWithReportStatus(List<Event> events) {
        if (events == null || events.isEmpty()) {
            return;
        }
        
        // 收集所有事件ID
        List<Long> eventIds = events.stream()
            .map(Event::getId)
            .distinct()
            .collect(java.util.stream.Collectors.toList());
        
        if (eventIds.isEmpty()) {
            return;
        }
        
        // 批量查询所有上报记录（使用 MyBatis-Plus 的 in 查询，一次查询所有）
        com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<ProvinceReport> reportWrapper = 
            new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<>();
        reportWrapper.eq(ProvinceReport::getDelFlag, "0")
            .in(ProvinceReport::getEventId, eventIds)
            .orderByDesc(ProvinceReport::getCreateTime);
        List<ProvinceReport> allReports = provinceReportService.list(reportWrapper);
        
        // 按事件ID分组，获取每个事件的最新上报记录
        Map<Long, ProvinceReport> latestReportMap = allReports.stream()
            .collect(java.util.stream.Collectors.groupingBy(
                ProvinceReport::getEventId,
                java.util.stream.Collectors.collectingAndThen(
                    java.util.stream.Collectors.toList(),
                    reports -> reports.stream()
                        .max(java.util.Comparator.comparing(ProvinceReport::getCreateTime))
                        .orElse(null)
                )
            ));
        
        // 统计每个事件的上报次数
        Map<Long, Long> reportCountMap = allReports.stream()
            .collect(java.util.stream.Collectors.groupingBy(
                ProvinceReport::getEventId,
                java.util.stream.Collectors.counting()
            ));
        
        // 填充每个事件的上报状态信息
        events.forEach(event -> {
            ProvinceReport latestReport = latestReportMap.get(event.getId());
            if (latestReport != null) {
                event.setProvinceReportStatus(latestReport.getStatus());
                event.setProvinceReportTime(latestReport.getCreateTime());
                event.setProvinceReportCount(reportCountMap.get(event.getId()).intValue());
                event.setHasProvinceReports(true);
                event.setProvinceReportOperator(latestReport.getCreateBy());
            } else {
                event.setProvinceReportStatus(null);
                event.setProvinceReportTime(null);
                event.setProvinceReportCount(0);
                event.setHasProvinceReports(false);
                event.setProvinceReportOperator(null);
            }
        });
    }
}