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.AdminCreateRequest;
import com.emotion.dto.request.AdminPageRequest;
import com.emotion.dto.request.AdminUpdateRequest;
import com.emotion.dto.response.AdminResponse;
import com.emotion.entity.Admin;
import com.emotion.exception.BusinessException;
import com.emotion.mapper.AdminMapper;
import com.emotion.service.AdminService;
import org.springframework.beans.BeanUtils;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 管理员服务实现类
 * 
 * @author huazhongmin
 * @date 2025-10-27
 */
@Service
public class AdminServiceImpl extends ServiceImpl<AdminMapper, Admin> implements AdminService {

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

    @Override
    public PageResult<AdminResponse> getPageWithResponse(AdminPageRequest request) {
        Page<Admin> page = new Page<>(request.getCurrent(), request.getSize());
        LambdaQueryWrapper<Admin> wrapper = new LambdaQueryWrapper<>();
        
        if (StringUtils.hasText(request.getKeyword())) {
            wrapper.and(w -> w.like(Admin::getAccount, request.getKeyword())
                    .or().like(Admin::getUsername, request.getKeyword())
                    .or().like(Admin::getEmail, request.getKeyword())
                    .or().like(Admin::getPhone, request.getKeyword()));
        }
        
        if (StringUtils.hasText(request.getAccount())) {
            wrapper.like(Admin::getAccount, request.getAccount());
        }
        
        if (StringUtils.hasText(request.getUsername())) {
            wrapper.like(Admin::getUsername, request.getUsername());
        }
        
        if (StringUtils.hasText(request.getEmail())) {
            wrapper.like(Admin::getEmail, request.getEmail());
        }
        
        if (StringUtils.hasText(request.getPhone())) {
            wrapper.like(Admin::getPhone, request.getPhone());
        }
        
        if (StringUtils.hasText(request.getRole())) {
            wrapper.eq(Admin::getRole, request.getRole());
        }
        
        if (request.getStatus() != null) {
            wrapper.eq(Admin::getStatus, request.getStatus());
        }
        
        if (StringUtils.hasText(request.getDepartment())) {
            wrapper.like(Admin::getDepartment, request.getDepartment());
        }

        wrapper.eq(Admin::getIsDeleted, 0);
        
        if (StringUtils.hasText(request.getOrderBy())) {
            if ("asc".equalsIgnoreCase(request.getOrderDirection())) {
                wrapper.orderByAsc(Admin::getCreateTime);
            } else {
                wrapper.orderByDesc(Admin::getCreateTime);
            }
        } else {
            wrapper.orderByDesc(Admin::getCreateTime);
        }
        
        IPage<Admin> adminPage = this.page(page, wrapper);
        
        List<AdminResponse> responseList = adminPage.getRecords().stream()
                .map(this::convertToResponse)
                .collect(Collectors.toList());
        
        PageResult<AdminResponse> result = new PageResult<>();
        result.setRecords(responseList);
        result.setTotal(adminPage.getTotal());
        result.setCurrent(adminPage.getCurrent());
        result.setSize(adminPage.getSize());
        result.setPages(adminPage.getPages());
        return result;
    }

    @Override
    public AdminResponse getAdminResponseById(String id) {
        Admin admin = this.getById(id);
        if (admin == null) {
            return null;
        }
        return convertToResponse(admin);
    }

    @Override
    public AdminResponse createAdminWithResponse(AdminCreateRequest request) {
        LambdaQueryWrapper<Admin> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Admin::getAccount, request.getAccount())
               .eq(Admin::getIsDeleted, 0);
        if (this.count(wrapper) > 0) {
            throw new BusinessException("账号已存在");
        }
        
        if (StringUtils.hasText(request.getEmail())) {
            wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Admin::getEmail, request.getEmail())
                   .eq(Admin::getIsDeleted, 0);
            if (this.count(wrapper) > 0) {
                throw new BusinessException("邮箱已存在");
            }
        }
        
        if (StringUtils.hasText(request.getPhone())) {
            wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Admin::getPhone, request.getPhone())
                   .eq(Admin::getIsDeleted, 0);
            if (this.count(wrapper) > 0) {
                throw new BusinessException("手机号已存在");
            }
        }
        
        Admin admin = new Admin();
        BeanUtils.copyProperties(request, admin);
        admin.setPassword(passwordEncoder.encode(request.getPassword()));
        admin.setStatus(1);
        admin.setLoginCount(0);
        
        boolean saved = this.save(admin);
        if (!saved) {
            return null;
        }
        
        return convertToResponse(admin);
    }

    @Override
    public AdminResponse updateAdminWithResponse(AdminUpdateRequest request) {
        Admin admin = this.getById(request.getId());
        if (admin == null) {
            throw new BusinessException("管理员不存在");
        }
        
        if (StringUtils.hasText(request.getEmail()) && !request.getEmail().equals(admin.getEmail())) {
            LambdaQueryWrapper<Admin> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Admin::getEmail, request.getEmail())
                   .ne(Admin::getId, request.getId())
                   .eq(Admin::getIsDeleted, 0);
            if (this.count(wrapper) > 0) {
                throw new BusinessException("邮箱已存在");
            }
        }
        
        if (StringUtils.hasText(request.getPhone()) && !request.getPhone().equals(admin.getPhone())) {
            LambdaQueryWrapper<Admin> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Admin::getPhone, request.getPhone())
                   .ne(Admin::getId, request.getId())
                   .eq(Admin::getIsDeleted, 0);
            if (this.count(wrapper) > 0) {
                throw new BusinessException("手机号已存在");
            }
        }
        
        if (StringUtils.hasText(request.getUsername())) {
            admin.setUsername(request.getUsername());
        }
        if (StringUtils.hasText(request.getEmail())) {
            admin.setEmail(request.getEmail());
        }
        if (StringUtils.hasText(request.getPhone())) {
            admin.setPhone(request.getPhone());
        }
        if (StringUtils.hasText(request.getAvatar())) {
            admin.setAvatar(request.getAvatar());
        }
        if (StringUtils.hasText(request.getRole())) {
            admin.setRole(request.getRole());
        }
        if (request.getPermissions() != null) {
            admin.setPermissions(request.getPermissions());
        }
        if (request.getStatus() != null) {
            admin.setStatus(request.getStatus());
        }
        if (StringUtils.hasText(request.getDepartment())) {
            admin.setDepartment(request.getDepartment());
        }
        if (StringUtils.hasText(request.getPosition())) {
            admin.setPosition(request.getPosition());
        }
        
        boolean updated = this.updateById(admin);
        if (!updated) {
            return null;
        }
        
        return convertToResponse(admin);
    }

    @Override
    public Admin getByAccount(String account) {
        LambdaQueryWrapper<Admin> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Admin::getAccount, account)
               .eq(Admin::getIsDeleted, 0);
        return this.getOne(wrapper);
    }

    @Override
    public Admin getByEmail(String email) {
        LambdaQueryWrapper<Admin> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Admin::getEmail, email)
               .eq(Admin::getIsDeleted, 0);
        return this.getOne(wrapper);
    }

    @Override
    public Admin getByPhone(String phone) {
        LambdaQueryWrapper<Admin> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Admin::getPhone, phone)
               .eq(Admin::getIsDeleted, 0);
        return this.getOne(wrapper);
    }

    private AdminResponse convertToResponse(Admin admin) {
        AdminResponse response = new AdminResponse();
        BeanUtils.copyProperties(admin, response);
        
        if (admin.getLastLoginTime() != null) {
            response.setLastLoginTime(admin.getLastLoginTime().format(DATE_TIME_FORMATTER));
        }
        if (admin.getCreateTime() != null) {
            response.setCreateTime(admin.getCreateTime().format(DATE_TIME_FORMATTER));
        }
        if (admin.getUpdateTime() != null) {
            response.setUpdateTime(admin.getUpdateTime().format(DATE_TIME_FORMATTER));
        }
        
        return response;
    }
}
