package com.emotion.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.emotion.common.PageResult;
import com.emotion.dto.request.ConversationCreateRequest;
import com.emotion.dto.request.ConversationPageRequest;
import com.emotion.dto.response.ConversationResponse;
import com.emotion.entity.Conversation;
import com.emotion.mapper.ConversationMapper;
import com.emotion.service.ConversationService;
import com.emotion.util.SnowflakeIdGenerator;
import com.emotion.util.UserContextUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 会话服务实现类
 *
 * @author huazhongmin
 * @date 2025-07-24
 */
@Service
public class ConversationServiceImpl extends ServiceImpl<ConversationMapper, Conversation> implements ConversationService {

    @Autowired
    private SnowflakeIdGenerator snowflakeIdGenerator;

    private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    @Override
    public IPage<Conversation> getPage(ConversationPageRequest request) {
        Page<Conversation> page = new Page<>(request.getCurrent(), request.getSize());
        LambdaQueryWrapper<Conversation> wrapper = new LambdaQueryWrapper<>();

        // 根据请求参数构建查询条件
        if (StringUtils.hasText(request.getUserId())) {
            wrapper.eq(Conversation::getUserId, request.getUserId());
        }

        if (StringUtils.hasText(request.getStatus())) {
            wrapper.eq(Conversation::getConversationStatus, request.getStatus());
        }

        if (StringUtils.hasText(request.getType())) {
            wrapper.eq(Conversation::getType, request.getType());
        }

        if (StringUtils.hasText(request.getKeyword())) {
            wrapper.and(w -> w.like(Conversation::getTitle, request.getKeyword())
                    .or().like(Conversation::getSummary, request.getKeyword()));
        }
        
        wrapper.eq(Conversation::getIsDeleted, 0).orderByDesc(Conversation::getCreateTime);
        return this.page(page, wrapper);
    }

    @Override
    public IPage<Conversation> getPageByUserId(ConversationPageRequest request) {
        Page<Conversation> page = new Page<>(request.getCurrent(), request.getSize());
        LambdaQueryWrapper<Conversation> wrapper = new LambdaQueryWrapper<>();

        // 必须提供userId参数
        if (!StringUtils.hasText(request.getUserId())) {
            throw new IllegalArgumentException("userId不能为空");
        }

        wrapper.eq(Conversation::getUserId, request.getUserId())
                .eq(Conversation::getIsDeleted, 0)
                .orderByDesc(Conversation::getCreateTime);
        return this.page(page, wrapper);
    }

    @Override
    public List<Conversation> getByUserId(String userId) {
        LambdaQueryWrapper<Conversation> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Conversation::getUserId, userId)
               .eq(Conversation::getIsDeleted, 0)
               .orderByDesc(Conversation::getCreateTime);
        return this.list(wrapper);
    }

    @Override
    public List<Conversation> getActiveByUserId(String userId) {
        LambdaQueryWrapper<Conversation> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Conversation::getUserId, userId)
                .eq(Conversation::getConversationStatus, "active")
               .eq(Conversation::getIsDeleted, 0)
                .orderByDesc(Conversation::getLastActiveTime);
        return this.list(wrapper);
    }

    @Override
    public Conversation getByCozeConversationId(String cozeConversationId) {
        LambdaQueryWrapper<Conversation> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Conversation::getCozeConversationId, cozeConversationId)
                .eq(Conversation::getIsDeleted, 0);
        return this.getOne(wrapper);
    }

    @Override
    public boolean updateMessageCount(String conversationId, Integer messageCount) {
        Conversation conversation = new Conversation();
        conversation.setId(conversationId);
        conversation.setMessageCount(messageCount);
        return this.updateById(conversation);
    }

    @Override
    public boolean updateStatus(String conversationId, Integer status) {
        Conversation conversation = new Conversation();
        conversation.setId(conversationId);
        // 根据status值设置对应的状态字符串
        String statusStr = "active";
        if (status == 1) {
            statusStr = "ended";
        } else if (status == 2) {
            statusStr = "archived";
        }
        conversation.setConversationStatus(statusStr);
        return this.updateById(conversation);
    }

    @Override
    public boolean updateEndTime(String conversationId, LocalDateTime endTime) {
        Conversation conversation = new Conversation();
        conversation.setId(conversationId);
        conversation.setEndTime(endTime);
        return this.updateById(conversation);
    }

    @Override
    public Long countByUserId(String userId) {
        LambdaQueryWrapper<Conversation> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Conversation::getUserId, userId)
               .eq(Conversation::getIsDeleted, 0);
        return this.count(wrapper);
    }

    @Override
    public Long countActiveByUserId(String userId) {
        LambdaQueryWrapper<Conversation> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Conversation::getUserId, userId)
                .eq(Conversation::getConversationStatus, "active")
               .eq(Conversation::getIsDeleted, 0);
        return this.count(wrapper);
    }

    @Override
    public List<Conversation> getForArchive(Integer days) {
        LocalDateTime archiveTime = LocalDateTime.now().minusDays(days);

        LambdaQueryWrapper<Conversation> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Conversation::getConversationStatus, "active")
                .lt(Conversation::getLastActiveTime, archiveTime)
               .eq(Conversation::getIsDeleted, 0)
                .orderByAsc(Conversation::getLastActiveTime);
        return this.list(wrapper);
    }

    @Override
    public boolean batchArchive(List<String> conversationIds) {
        for (String conversationId : conversationIds) {
            Conversation conversation = new Conversation();
            conversation.setId(conversationId);
            conversation.setConversationStatus("archived");
            this.updateById(conversation);
        }
        return true;
    }

    @Override
    public Conversation createConversation(String userId, String title, String cozeConversationId) {
        Conversation conversation = new Conversation();
        conversation.setId(snowflakeIdGenerator.nextIdAsString()); // 使用雪花算法生成ID
        conversation.setUserId(userId);
        conversation.setTitle(title);
        conversation.setCozeConversationId(cozeConversationId);
        conversation.setUserType("registered");
        conversation.setType("chat");
        conversation.setConversationStatus("active");
        conversation.setStartTime(LocalDateTime.now());
        conversation.setLastActiveTime(LocalDateTime.now());
        conversation.setMessageCount(0);
        conversation.setTotalTokens(0);
        conversation.setTotalCost(java.math.BigDecimal.ZERO);

        this.save(conversation);
        return conversation;
    }

    @Override
    public boolean endConversation(String conversationId) {
        Conversation conversation = new Conversation();
        conversation.setId(conversationId);
        conversation.setConversationStatus("ended");
        conversation.setEndTime(LocalDateTime.now());
        return this.updateById(conversation);
    }

    @Override
    public PageResult<ConversationResponse> getPageWithResponse(ConversationPageRequest request) {
        IPage<Conversation> page = this.getPage(request);
        return convertPageToResponse(page);
    }

    @Override
    public PageResult<ConversationResponse> getPageByUserIdWithResponse(ConversationPageRequest request) {
        IPage<Conversation> page = this.getPageByUserId(request);
        return convertPageToResponse(page);
    }

    @Override
    public ConversationResponse getConversationResponseById(String id) {
        Conversation conversation = this.getById(id);
        if (conversation == null) {
            return null;
        }
        return convertToResponse(conversation);
    }

    @Override
    public List<ConversationResponse> getByUserIdWithResponse(String userId) {
        List<Conversation> conversations = this.getByUserId(userId);
        return conversations.stream()
                .map(this::convertToResponse)
                .collect(Collectors.toList());
    }

    @Override
    public List<ConversationResponse> getActiveConversationsWithResponse() {
        // 实现获取活跃对话的逻辑
        LambdaQueryWrapper<Conversation> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Conversation::getConversationStatus, "active")
                .eq(Conversation::getIsDeleted, 0)
                .orderByDesc(Conversation::getLastActiveTime);
        List<Conversation> conversations = this.list(wrapper);
        return conversations.stream()
                .map(this::convertToResponse)
                .collect(Collectors.toList());
    }

    @Override
    public List<ConversationResponse> getArchivedConversationsWithResponse() {
        // 实现获取归档对话的逻辑
        LambdaQueryWrapper<Conversation> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Conversation::getConversationStatus, "archived")
                .eq(Conversation::getIsDeleted, 0)
                .orderByDesc(Conversation::getCreateTime);
        List<Conversation> conversations = this.list(wrapper);
        return conversations.stream()
                .map(this::convertToResponse)
                .collect(Collectors.toList());
    }

    @Override
    public boolean archiveConversation(String id) {
        Conversation conversation = new Conversation();
        conversation.setId(id);
        conversation.setConversationStatus("archived");
        return this.updateById(conversation);
    }

    @Override
    public boolean activateConversation(String id) {
        Conversation conversation = new Conversation();
        conversation.setId(id);
        conversation.setConversationStatus("active");
        return this.updateById(conversation);
    }

    @Override
    public ConversationResponse createConversationWithResponse(ConversationCreateRequest request,
            HttpServletRequest httpRequest) {
        // 获取客户端IP地址
        String clientIp = UserContextUtils.getClientIpAddress(httpRequest);

        Conversation conversation = this.createConversation(
                request.getUserId(),
                request.getTitle(),
                null // cozeConversationId
        );

        // 设置客户端IP
        conversation.setClientIp(clientIp);
        this.updateById(conversation);

        return convertToResponse(conversation);
    }

    @Override
    public ConversationResponse updateConversationWithResponse(ConversationCreateRequest request) {
        Conversation conversation = this.getById(request.getId()); // 修复：使用ID而不是userId
        if (conversation == null) {
            return null;
        }

        // 更新字段
        if (request.getTitle() != null) {
            conversation.setTitle(request.getTitle());
        }
        if (request.getType() != null) {
            conversation.setType(request.getType());
        }

        this.updateById(conversation);
        return convertToResponse(conversation);
    }

    @Override
    public boolean updateConversationStatus(String id, String status) {
        Conversation conversation = new Conversation();
        conversation.setId(id);
        conversation.setConversationStatus(status);
        return this.updateById(conversation);
    }

    /**
     * 转换为响应对象
     */
    private ConversationResponse convertToResponse(Conversation conversation) {
        ConversationResponse response = new ConversationResponse();
        BeanUtils.copyProperties(conversation, response);
        response.setId(conversation.getId());
        response.setStatus(conversation.getConversationStatus());
        if (conversation.getCreateTime() != null) {
            response.setCreateTime(conversation.getCreateTime().format(DATE_TIME_FORMATTER));
        }
        if (conversation.getUpdateTime() != null) {
            response.setUpdateTime(conversation.getUpdateTime().format(DATE_TIME_FORMATTER));
        }
        if (conversation.getLastActiveTime() != null) {
            response.setLastMessageTime(conversation.getLastActiveTime().format(DATE_TIME_FORMATTER));
        }
        return response;
    }

    /**
     * 转换分页对象为响应对象
     */
    private PageResult<ConversationResponse> convertPageToResponse(IPage<Conversation> page) {
        PageResult<ConversationResponse> responsePage = new PageResult<>();
        responsePage.setCurrent(page.getCurrent());
        responsePage.setSize(page.getSize());
        responsePage.setTotal(page.getTotal());
        responsePage.setPages(page.getPages());
        responsePage.setRecords(
                page.getRecords().stream()
                        .map(this::convertToResponse)
                        .collect(Collectors.toList()));
        return responsePage;
    }
}