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.BasePageRequest;
import com.emotion.common.PageResult;
import com.emotion.dto.request.guest.GuestUserCreateRequest;
import com.emotion.dto.request.guest.GuestUserUpdateRequest;
import com.emotion.dto.response.guest.GuestUserResponse;
import com.emotion.entity.GuestUser;
import com.emotion.mapper.GuestUserMapper;
import com.emotion.service.GuestUserService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 访客用户服务实现类
 * 
 * @author huazhongmin
 * @date 2025-09-08
 */
@Service
public class GuestUserServiceImpl extends ServiceImpl<GuestUserMapper, GuestUser> implements GuestUserService {

    @Override
    public IPage<GuestUser> getPage(BasePageRequest request) {
        Page<GuestUser> page = new Page<>(request.getCurrent(), request.getSize());
        LambdaQueryWrapper<GuestUser> wrapper = new LambdaQueryWrapper<>();
        
        if (StringUtils.hasText(request.getKeyword())) {
            wrapper.like(GuestUser::getNickname, request.getKeyword());
        }
        
        wrapper.eq(GuestUser::getIsDeleted, 0).orderByDesc(GuestUser::getCreateTime);
        return this.page(page, wrapper);
    }

    @Override
    public PageResult<GuestUserResponse> getPageWithResponse(BasePageRequest request) {
        IPage<GuestUser> page = getPage(request);
        List<GuestUserResponse> responses = page.getRecords().stream()
                .map(this::convertToResponse)
                .collect(Collectors.toList());
        PageResult<GuestUserResponse> pageResult = new PageResult<>();
        pageResult.setRecords(responses);
        pageResult.setCurrent(page.getCurrent());
        pageResult.setSize(page.getSize());
        pageResult.setTotal(page.getTotal());
        pageResult.setPages(page.getPages());
        return pageResult;
    }

    @Override
    public GuestUserResponse getGuestUserResponseById(String id) {
        GuestUser guestUser = this.getById(id);
        if (guestUser == null || guestUser.getIsDeleted() == 1) {
            return null;
        }
        return convertToResponse(guestUser);
    }

    @Override
    public GuestUser getByDeviceId(String deviceId) {
        LambdaQueryWrapper<GuestUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(GuestUser::getDeviceInfo, deviceId)
               .eq(GuestUser::getIsDeleted, 0);
        return this.getOne(wrapper);
    }

    @Override
    public List<GuestUser> getByIpAddress(String ipAddress) {
        LambdaQueryWrapper<GuestUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(GuestUser::getIpAddress, ipAddress)
               .eq(GuestUser::getIsDeleted, 0)
               .orderByDesc(GuestUser::getCreateTime);
        return this.list(wrapper);
    }

    @Override
    public List<GuestUser> getByUserAgent(String userAgent) {
        LambdaQueryWrapper<GuestUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(GuestUser::getUserAgent, userAgent)
               .eq(GuestUser::getIsDeleted, 0)
               .orderByDesc(GuestUser::getCreateTime);
        return this.list(wrapper);
    }

    @Override
    public List<GuestUser> getByStatus(String status) {
        // GuestUser实体中没有status字段，暂时返回空列表
        return Collections.emptyList();
    }

    @Override
    public List<GuestUser> getByTimeRange(LocalDateTime startTime, LocalDateTime endTime) {
        LambdaQueryWrapper<GuestUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.between(GuestUser::getCreateTime, startTime, endTime)
               .eq(GuestUser::getIsDeleted, 0)
               .orderByDesc(GuestUser::getCreateTime);
        return this.list(wrapper);
    }

    @Override
    public List<GuestUser> getByLastActiveTimeRange(LocalDateTime startTime, LocalDateTime endTime) {
        LambdaQueryWrapper<GuestUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.between(GuestUser::getLastActiveTime, startTime, endTime)
               .eq(GuestUser::getIsDeleted, 0)
               .orderByDesc(GuestUser::getLastActiveTime);
        return this.list(wrapper);
    }

    @Override
    public Long countByStatus(String status) {
        // GuestUser实体中没有status字段，暂时返回0
        return 0L;
    }

    @Override
    public Long countByIpAddress(String ipAddress) {
        LambdaQueryWrapper<GuestUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(GuestUser::getIpAddress, ipAddress)
               .eq(GuestUser::getIsDeleted, 0);
        return this.count(wrapper);
    }

    @Override
    public Long countTodayNewGuests() {
        LocalDateTime today = LocalDateTime.now().withHour(0).withMinute(0).withSecond(0).withNano(0);
        LocalDateTime tomorrow = today.plusDays(1);

        LambdaQueryWrapper<GuestUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.between(GuestUser::getCreateTime, today, tomorrow)
               .eq(GuestUser::getIsDeleted, 0);
        return this.count(wrapper);
    }

    @Override
    public Long countActiveGuests(Integer days) {
        LocalDateTime activeTime = LocalDateTime.now().minusDays(days);

        LambdaQueryWrapper<GuestUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.ge(GuestUser::getLastActiveTime, activeTime)
               .eq(GuestUser::getIsDeleted, 0);
        return this.count(wrapper);
    }

    @Override
    public List<GuestUser> getRecentVisitors(Integer limit) {
        LambdaQueryWrapper<GuestUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(GuestUser::getIsDeleted, 0)
               .orderByDesc(GuestUser::getLastActiveTime)
               .last("LIMIT " + limit);
        return this.list(wrapper);
    }

    @Override
    public List<GuestUser> getInactiveGuests(Integer days) {
        LocalDateTime inactiveTime = LocalDateTime.now().minusDays(days);

        LambdaQueryWrapper<GuestUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.lt(GuestUser::getLastActiveTime, inactiveTime)
               .eq(GuestUser::getIsDeleted, 0)
               .orderByAsc(GuestUser::getLastActiveTime);
        return this.list(wrapper);
    }

    @Override
    public List<GuestUser> getByVisitCountRange(Integer minVisits, Integer maxVisits) {
        // GuestUser实体中没有visitCount字段，暂时返回空列表
        return Collections.emptyList();
    }

    @Override
    public Double getAvgVisitCount() {
        // 这里需要自定义SQL查询平均值，暂时返回0
        return 0.0;
    }

    @Override
    public boolean updateLastActiveTime(String id, LocalDateTime lastActiveTime) {
        GuestUser guestUser = new GuestUser();
        guestUser.setId(id);
        guestUser.setLastActiveTime(lastActiveTime);
        return this.updateById(guestUser);
    }

    @Override
    public boolean incrementVisitCount(String id) {
        // GuestUser实体中没有visitCount字段，暂时返回false
        return false;
    }

    @Override
    public boolean updateStatus(String id, String status) {
        // GuestUser实体中没有status字段，暂时返回false
        return false;
    }

    @Override
    public GuestUser getOrCreateByDeviceInfo(String deviceId, String ipAddress, String userAgent) {
        // 先尝试根据设备信息查找
        GuestUser existingUser = getByDeviceId(deviceId);
        if (existingUser != null) {
            // 更新最后活跃时间
            updateLastActiveTime(existingUser.getId(), LocalDateTime.now());
            return existingUser;
        }

        // 如果不存在，创建新的访客用户
        return createGuestUser(deviceId, ipAddress, userAgent, null);
    }

    @Override
    public boolean cleanExpiredGuests(Integer days) {
        LocalDateTime expireTime = LocalDateTime.now().minusDays(days);

        LambdaQueryWrapper<GuestUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.lt(GuestUser::getLastActiveTime, expireTime);

        // 使用 MyBatis-Plus 的 remove 方法，自动处理逻辑删除
        return this.remove(wrapper);
    }

    @Override
    public GuestUser createGuestUser(String deviceId, String ipAddress, String userAgent, String location) {
        GuestUser guestUser = new GuestUser();
        guestUser.setGuestUserId("guest_" + System.currentTimeMillis());
        guestUser.setIpAddress(ipAddress);
        guestUser.setUserAgent(userAgent);
        guestUser.setNickname("访客用户");
        guestUser.setAvatar("default_avatar.png");
        guestUser.setLastActiveTime(LocalDateTime.now());
        guestUser.setConversationCount(0);
        guestUser.setMessageCount(0);
        guestUser.setLocation(location);
        guestUser.setDeviceInfo(deviceId);

        this.save(guestUser);
        return guestUser;
    }

    @Override
    public GuestUserResponse createGuestUserWithResponse(GuestUserCreateRequest request) {
        GuestUser guestUser = createGuestUser(
                request.getDeviceId(),
                request.getIpAddress(),
                request.getUserAgent(),
                request.getLocation());
        return convertToResponse(guestUser);
    }

    @Override
    public GuestUserResponse updateGuestUserWithResponse(GuestUserUpdateRequest request) {
        GuestUser guestUser = this.getById(request.getId());
        if (guestUser == null || guestUser.getIsDeleted() == 1) {
            return null;
        }

        // 只更新非空字段
        if (StringUtils.hasText(request.getNickname())) {
            guestUser.setNickname(request.getNickname());
        }
        if (StringUtils.hasText(request.getAvatar())) {
            guestUser.setAvatar(request.getAvatar());
        }
        if (StringUtils.hasText(request.getLocation())) {
            guestUser.setLocation(request.getLocation());
        }

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

    @Override
    public boolean deleteGuestUser(String id) {
        GuestUser guestUser = this.getById(id);
        if (guestUser == null) {
            return false;
        }

        // 使用 MyBatis-Plus 的 removeById 方法，自动处理逻辑删除
        return this.removeById(id);
    }

    /**
     * 将实体转换为响应对象
     */
    private GuestUserResponse convertToResponse(GuestUser guestUser) {
        if (guestUser == null) {
            return null;
        }

        GuestUserResponse response = new GuestUserResponse();
        BeanUtils.copyProperties(guestUser, response);
        response.setId(guestUser.getId());
        if (guestUser.getCreateTime() != null) {
            response.setCreateTime(guestUser.getCreateTime().toString());
        }
        if (guestUser.getUpdateTime() != null) {
            response.setUpdateTime(guestUser.getUpdateTime().toString());
        }
        return response;
    }
}