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

import java.util.Collections;
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.emergency.alert.constant.AlertConvertReviewStatus;
import com.aegis.emergency.alert.constant.AlertLogAction;
import com.aegis.emergency.alert.constant.AlertStatus;
import com.aegis.emergency.alert.domain.DutyAlert;
import com.aegis.emergency.alert.domain.DutyAlertConvert;
import com.aegis.emergency.alert.mapper.DutyAlertConvertMapper;
import com.aegis.emergency.alert.service.DutyAlertLogService;
import com.aegis.emergency.alert.service.DutyAlertConvertService;
import com.aegis.emergency.alert.service.DutyAlertService;
import com.aegis.emergency.event.service.IEventService;
import com.aegis.emergency.event.domain.Event;
import com.aegis.emergency.event.constant.EventStatus;

/**
 * 转事件 Service 实现
 *
 * 管理转事件申请、审核及事件创建流程
 *
 * @author aegis
 */
@Service
public class DutyAlertConvertServiceImpl extends ServiceImpl<DutyAlertConvertMapper, DutyAlertConvert>
        implements DutyAlertConvertService {

    @Autowired
    private DutyAlertService dutyAlertService;

    @Autowired
    private DutyAlertLogService alertLogService;

    @Autowired
    private IEventService eventService;

    @Override
    public List<DutyAlertConvert> listByCondition(DutyAlertConvert condition) {
        LambdaQueryWrapper<DutyAlertConvert> wrapper = new LambdaQueryWrapper<>();
        if (condition != null) {
            if (condition.getAlertId() != null) {
                wrapper.eq(DutyAlertConvert::getAlertId, condition.getAlertId());
            }
            if (StringUtils.isNotEmpty(condition.getReviewStatus())) {
                wrapper.eq(DutyAlertConvert::getReviewStatus, condition.getReviewStatus());
            }
            if (condition.getConvertTime() != null) {
                wrapper.ge(DutyAlertConvert::getConvertTime, condition.getConvertTime());
            }
        }
        wrapper.orderByDesc(DutyAlertConvert::getConvertTime);
        return list(wrapper);
    }

    @Override
    public DutyAlertConvert getByAlertId(Long alertId) {
        if (alertId == null) {
            throw new ServiceException("警情ID不能为空");
        }
        LambdaQueryWrapper<DutyAlertConvert> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DutyAlertConvert::getAlertId, alertId)
                .orderByDesc(DutyAlertConvert::getConvertTime)
                .last("LIMIT 1");
        return getOne(wrapper);
    }

    /**
     * 批量查询转事件记录（根据警情ID列表，返回每个警情的最新一条记录）
     */
    @Override
    public Map<Long, DutyAlertConvert> getLatestByAlertIds(List<Long> alertIds) {
        if (alertIds == null || alertIds.isEmpty()) {
            return Collections.emptyMap();
        }
        
        // 使用 IN 查询，一次性获取所有转事件记录
        LambdaQueryWrapper<DutyAlertConvert> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(DutyAlertConvert::getAlertId, alertIds)
               .orderByDesc(DutyAlertConvert::getConvertTime);
        
        List<DutyAlertConvert> allConverts = list(wrapper);
        
        // 在内存中筛选每个警情的最新一条记录
        Map<Long, DutyAlertConvert> result = new HashMap<>();
        for (DutyAlertConvert convert : allConverts) {
            Long alertId = convert.getAlertId();
            // 如果该警情还没有记录，或者当前记录更新，则更新
            if (!result.containsKey(alertId) || 
                (convert.getConvertTime() != null && 
                 result.get(alertId).getConvertTime() != null &&
                 convert.getConvertTime().after(result.get(alertId).getConvertTime()))) {
                result.put(alertId, convert);
            }
        }
        
        return result;
    }

    @Override
    @Transactional
    public boolean applyConvert(DutyAlertConvert convert) {
        if (convert == null) {
            throw new ServiceException("转事件信息不能为空");
        }
        if (convert.getAlertId() == null) {
            throw new ServiceException("警情ID不能为空");
        }
        if (StringUtils.isBlank(convert.getConvertReason())) {
            throw new ServiceException("转事件原因说明不能为空");
        }

        DutyAlert alert = dutyAlertService.getById(convert.getAlertId());
        if (alert == null) {
            throw new ServiceException("警情不存在或已删除");
        }

        // 检查是否已经存在该警情的转事件记录
        DutyAlertConvert existingConvert = getByAlertId(convert.getAlertId());
        if (existingConvert != null) {
            AlertConvertReviewStatus existingStatus = AlertConvertReviewStatus.fromCode(existingConvert.getReviewStatus());
            // 如果已存在且状态不是 rejected，不允许重复申请
            if (existingStatus != null && existingStatus != AlertConvertReviewStatus.REJECTED) {
                throw new ServiceException("该警情已存在转事件申请，无法重复提交");
            }
            // 如果已存在且状态是 rejected，更新现有记录
            if (existingStatus != null && existingStatus == AlertConvertReviewStatus.REJECTED) {
                String operator = SecurityUtils.getUsername();
                boolean reviewRequired = Boolean.TRUE.equals(convert.getReviewRequired());
                
                // 更新现有记录
                existingConvert.setConvertReason(convert.getConvertReason());
                existingConvert.setReviewRequired(reviewRequired);
                existingConvert.setReviewStatus(reviewRequired ? 
                    AlertConvertReviewStatus.PENDING.getCode() : AlertConvertReviewStatus.APPROVED.getCode());
                existingConvert.setConvertTime(new Date());
                existingConvert.setUpdateBy(operator);
                existingConvert.setUpdateTime(new Date());
                
                if (!updateById(existingConvert)) {
                    return false;
                }
                
                alertLogService.recordLog(convert.getAlertId(), AlertLogAction.CONVERT_APPLY, existingConvert);
                
                // 如果无需审核，默认视作已审核通过
                if (!reviewRequired) {
                    alert.setStatus(AlertStatus.CONVERTED.getCode());
                    alert.setUpdateBy(operator);
                    alert.setUpdateTime(new Date());
                    boolean updated = dutyAlertService.updateById(alert);
                    if (updated) {
                        alertLogService.recordLog(convert.getAlertId(), AlertLogAction.ALERT_CONVERTED, alert);
                    }
                }
                
                return true;
            }
        }

        String operator = SecurityUtils.getUsername();
        convert.setCreateBy(operator);
        convert.setCreateTime(new Date());
        convert.setUpdateBy(operator);
        convert.setUpdateTime(new Date());
        convert.setOperatorId(null); // 操作人信息可按需扩展
        convert.setOperatorName(operator);
        if (convert.getConvertTime() == null) {
            convert.setConvertTime(new Date());
        }

        boolean reviewRequired = Boolean.TRUE.equals(convert.getReviewRequired());
        convert.setReviewRequired(reviewRequired);
        convert.setReviewStatus(reviewRequired ? AlertConvertReviewStatus.PENDING.getCode()
                : AlertConvertReviewStatus.APPROVED.getCode());

        if (!save(convert)) {
            return false;
        }

        alertLogService.recordLog(convert.getAlertId(), AlertLogAction.CONVERT_APPLY, convert);

        // 如果无需审核，默认视作已审核通过，后续可创建事件
        if (!reviewRequired) {
            Event event = buildEventFromAlert(alert, convert);
            if (eventService.save(event)) {
                convert.setEventId(event.getId());
                updateById(convert);
                alert.setStatus(AlertStatus.CONVERTED.getCode());
                alert.setUpdateBy(operator);
                alert.setUpdateTime(new Date());
                boolean updated = dutyAlertService.updateById(alert);
                if (updated) {
                    alertLogService.recordLog(convert.getAlertId(), AlertLogAction.ALERT_CONVERTED, alert);
                }
                Map<String, Object> payload = new HashMap<>();
                payload.put("eventId", event.getId());
                payload.put("eventNo", event.getEventNo());
                payload.put("eventTitle", event.getTitle());
                alertLogService.recordLog(convert.getAlertId(), AlertLogAction.CONVERT_EVENT_CREATED, payload);
            } else {
                throw new ServiceException("事件创建失败");
            }
        }

        return true;
    }

    @Override
    @Transactional
    public boolean approveConvert(Long convertId, String reviewComment) {
        DutyAlertConvert convert = validateConvertForReview(convertId);

        String operator = SecurityUtils.getUsername();
        convert.setReviewStatus(AlertConvertReviewStatus.APPROVED.getCode());
        convert.setRemark(reviewComment);
        convert.setUpdateBy(operator);
        convert.setUpdateTime(new Date());
        convert.setConvertTime(new Date());

        if (!updateById(convert)) {
            return false;
        }

        DutyAlert alert = dutyAlertService.getById(convert.getAlertId());
        if (alert == null) {
            throw new ServiceException("警情不存在或已删除");
        }

        alert.setStatus(AlertStatus.CONVERTED.getCode());
        alert.setUpdateBy(operator);
        alert.setUpdateTime(new Date());
        dutyAlertService.updateById(alert);
        alertLogService.recordLog(convert.getAlertId(), AlertLogAction.ALERT_CONVERTED, alert);
        alertLogService.recordLog(convert.getAlertId(), AlertLogAction.CONVERT_APPROVE, convert);

        Event event = buildEventFromAlert(alert, convert);
        if (eventService.save(event)) {
            convert.setEventId(event.getId());
            updateById(convert);
            Map<String, Object> payload = new HashMap<>();
            payload.put("eventId", event.getId());
            payload.put("eventNo", event.getEventNo());
            payload.put("eventTitle", event.getTitle());
            alertLogService.recordLog(convert.getAlertId(), AlertLogAction.CONVERT_EVENT_CREATED, payload);
        } else {
            throw new ServiceException("事件创建失败");
        }

        return true;
    }

    @Override
    @Transactional
    public boolean rejectConvert(Long convertId, String reviewComment) {
        DutyAlertConvert convert = validateConvertForReview(convertId);

        String operator = SecurityUtils.getUsername();
        convert.setReviewStatus(AlertConvertReviewStatus.REJECTED.getCode());
        convert.setRemark(reviewComment);
        convert.setUpdateBy(operator);
        convert.setUpdateTime(new Date());

        boolean updated = updateById(convert);
        if (updated) {
            alertLogService.recordLog(convert.getAlertId(), AlertLogAction.CONVERT_REJECT, convert);
            
            // 审核驳回后，回退警情状态为 received（如果当前状态是 converted 或 transferred）
            // 注意：高等级警情在提交转事件申请时不会立即更新状态，所以可能已经是 received
            DutyAlert alert = dutyAlertService.getById(convert.getAlertId());
            if (alert != null) {
                String currentStatus = alert.getStatus();
                // 如果状态是 converted（无需审核直接通过，或审核通过后），回退为 received
                // 如果状态是 transferred（之前有转警申请），也应该回退为 received，以便用户可以重新选择
                if (AlertStatus.CONVERTED.getCode().equals(currentStatus) || 
                    AlertStatus.TRANSFERRED.getCode().equals(currentStatus)) {
                    alert.setStatus(AlertStatus.RECEIVED.getCode());
                    alert.setUpdateBy(operator);
                    alert.setUpdateTime(new Date());
                    dutyAlertService.updateById(alert);
                }
            }
        }
        return updated;
    }

    private DutyAlertConvert validateConvertForReview(Long convertId) {
        if (convertId == null) {
            throw new ServiceException("转事件记录ID不能为空");
        }
        DutyAlertConvert convert = super.getById(convertId);
        if (convert == null) {
            throw new ServiceException("转事件记录不存在");
        }
        if (convert.getReviewRequired() != null && convert.getReviewRequired()) {
            AlertConvertReviewStatus status = AlertConvertReviewStatus.fromCode(convert.getReviewStatus());
            if (status == null || status != AlertConvertReviewStatus.PENDING) {
                throw new ServiceException("该转事件记录已审核，无法重复操作");
            }
        } else {
            throw new ServiceException("该转事件申请无需审核");
        }
        return convert;
    }

    private Event buildEventFromAlert(DutyAlert alert, DutyAlertConvert convert) {
        Event event = new Event();
        String title = StringUtils.isNotBlank(alert.getSummary())
                ? alert.getSummary()
                : "警情转事件-" + alert.getAlertNo();
        event.setTitle(title);
        event.setSummary(convert.getConvertReason());
        event.setSource("alert_convert");
        event.setAlertId(alert.getId());
        event.setLocation(alert.getLocation());
        event.setLongitude(alert.getLongitude());
        event.setLatitude(alert.getLatitude());
        event.setLevel(alert.getInitialLevel());
        event.setType(alert.getSourceChannel());
        event.setOccurredAt(alert.getOccurredAt() != null ? alert.getOccurredAt() : new Date());
        event.setStatus(EventStatus.PENDING.getCode());
        event.setRemark("由警情转事件创建，申请ID：" + convert.getId());
        return event;
    }
}