package org.dromara.main.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.service.OssService;
import org.dromara.common.tenant.helper.TenantHelper;
import org.dromara.main.domain.MainBackCandidate;
import org.dromara.main.domain.MainPosition;
import org.dromara.main.domain.MainStudent;
import org.dromara.main.mapper.MainBackCandidateMapper;
import org.dromara.main.mapper.MainPositionMapper;
import org.dromara.main.mapper.MainStudentMapper;
import org.dromara.main.service.IMainBackCandidateService;
import org.dromara.main.service.IMainMessageService;
import org.dromara.system.domain.SysUser;
import org.dromara.system.domain.bo.SysUserBo;
import org.dromara.system.domain.SysTenant;
import org.dromara.system.mapper.SysTenantMapper;
import org.dromara.system.mapper.SysUserMapper;
import org.dromara.system.service.ISysUserService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 背调候选人Service实现
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class MainBackCandidateServiceImpl implements IMainBackCandidateService {

    private final MainBackCandidateMapper mainBackCandidateMapper;
    private final MainPositionMapper mainPositionMapper;
    private final MainStudentMapper mainStudentMapper;
    private final SysTenantMapper sysTenantMapper;
    private final SysUserMapper sysUserMapper;
    private final ISysUserService sysUserService;
    private final OssService ossService;
    private final IMainMessageService mainMessageService;

    @Override
    public List<Map<String, Object>> getStudentOfferList(Long studentId) {
        LambdaQueryWrapper<MainBackCandidate> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(MainBackCandidate::getStudentId, studentId)
               .eq(MainBackCandidate::getDelFlag, "0")
               .orderByDesc(MainBackCandidate::getCreateTime);
        List<MainBackCandidate> list = mainBackCandidateMapper.selectList(wrapper);

        // 批量查询岗位名称和企业名称
        List<Long> postIds = list.stream().map(MainBackCandidate::getPostId).distinct().collect(Collectors.toList());
        List<String> tenantIds = list.stream().map(MainBackCandidate::getTenantId).distinct().collect(Collectors.toList());

        Map<Long, String> postNameMap = new HashMap<>();
        if (!postIds.isEmpty()) {
            List<MainPosition> positions = mainPositionMapper.selectByIds(postIds);
            postNameMap.putAll(positions.stream()
                .collect(Collectors.toMap(MainPosition::getId, MainPosition::getPostName, (v1, v2) -> v1)));
        }

        Map<String, String> companyNameMap = new HashMap<>();
        for (String tenantId : tenantIds) {
            SysTenant tenant = sysTenantMapper.selectOne(new LambdaQueryWrapper<SysTenant>()
                .eq(SysTenant::getTenantId, tenantId));
            if (tenant != null) {
                companyNameMap.put(tenantId, tenant.getCompanyName());
            }
        }

        // 组装返回数据
        return list.stream().map(item -> {
            Map<String, Object> map = new HashMap<>();
            map.put("id", item.getId());
            map.put("postId", item.getPostId());
            map.put("postName", postNameMap.getOrDefault(item.getPostId(), "未知岗位"));
            map.put("tenantId", item.getTenantId());
            map.put("companyName", companyNameMap.getOrDefault(item.getTenantId(), "未知企业"));
            map.put("studentId", item.getStudentId());
            map.put("enterpriseStatus", item.getEnterpriseStatus());
            map.put("studentStatus", item.getStudentStatus());
            // offerFileUrl 存的是ossId，需要转为真实URL
            String rawOfferUrl = item.getOfferFileUrl();
            if (rawOfferUrl != null && !rawOfferUrl.isBlank()) {
                try {
                    String realUrl = ossService.selectUrlByIds(rawOfferUrl);
                    map.put("offerFileUrl", realUrl != null ? realUrl : rawOfferUrl);
                } catch (Exception e) {
                    map.put("offerFileUrl", rawOfferUrl);
                }
            } else {
                map.put("offerFileUrl", null);
            }
            map.put("offerFileName", item.getOfferFileName());
            map.put("offerTime", item.getOfferTime());
            map.put("studentReplyTime", item.getStudentReplyTime());
            map.put("remark", item.getRemark());
            map.put("createTime", item.getCreateTime());
            return map;
        }).collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean acceptOffer(Long id, Long studentId) {
        MainBackCandidate candidate = mainBackCandidateMapper.selectById(id);
        if (candidate == null) {
            throw new ServiceException("候选记录不存在");
        }
        if (!candidate.getStudentId().equals(studentId)) {
            throw new ServiceException("无权操作该记录");
        }
        if (!"adopted".equals(candidate.getEnterpriseStatus())) {
            throw new ServiceException("企业未发出Offer，无法接受");
        }
        if (!"pending".equals(candidate.getStudentStatus())) {
            throw new ServiceException("已处理过该Offer");
        }

        MainBackCandidate update = new MainBackCandidate();
        update.setId(id);
        update.setStudentStatus("accepted");
        update.setStudentReplyTime(LocalDateTime.now());
        // 同时更新旧status字段保持兼容
        update.setStatus("adopted");

        boolean updated = mainBackCandidateMapper.updateById(update) > 0;

        // 接受Offer后，将学员添加到企业的员工表（sys_user）
        if (updated) {
            try {
                addEmployeeFromStudent(candidate);
            } catch (Exception e) {
                log.warn("接受Offer后添加企业员工失败，candidateId={}, error={}", id, e.getMessage(), e);
                // 不影响Offer接受的主流程
            }
            // 发送通知消息
            sendCandidateNotification(candidate, "投递进度更新", "您已接受Offer");
        }

        return updated;
    }

    /**
     * 将学员添加到企业的员工表（sys_user）
     */
    private void addEmployeeFromStudent(MainBackCandidate candidate) {
        String tenantId = candidate.getTenantId();
        Long studentId = candidate.getStudentId();
        if (tenantId == null || studentId == null) {
            log.warn("租户ID或学员ID为空，跳过添加员工");
            return;
        }

        // 查询学员信息
        MainStudent student = mainStudentMapper.selectById(studentId);
        if (student == null) {
            log.warn("学员不存在，studentId={}", studentId);
            return;
        }

        // 在目标租户下检查是否已存在该手机号的用户
        SysUser existingUser = TenantHelper.dynamic(tenantId, () -> {
            return sysUserMapper.selectOne(
                new LambdaQueryWrapper<SysUser>()
                    .eq(SysUser::getPhonenumber, student.getMobile())
                    .eq(SysUser::getDelFlag, "0")
                    .last("LIMIT 1")
            );
        });

        if (existingUser != null) {
            log.info("企业租户{}下已存在手机号{}的用户，跳过创建", tenantId, student.getMobile());
            return;
        }

        // 在目标租户下创建企业员工账号
        SysUserBo userBo = new SysUserBo();
        userBo.setUserName(student.getMobile() != null ? student.getMobile() : "student_" + studentId);
        userBo.setNickName(student.getName() != null ? student.getName() : "学员");
        userBo.setPhonenumber(student.getMobile());
        userBo.setEmail(student.getEmail());
        userBo.setSex(student.getGender());
        userBo.setAvatar(student.getAvatar());
        userBo.setPassword(student.getMobile() != null ? student.getMobile() : "123456");
        userBo.setStatus("0"); // 正常状态
        userBo.setRemark("学员接受Offer自动创建");

        try {
            boolean created = TenantHelper.dynamic(tenantId, () -> {
                return sysUserService.registerUser(userBo, tenantId);
            });
            if (created) {
                log.info("成功为企业租户{}创建员工账号，手机号={}", tenantId, student.getMobile());
            }
        } catch (Exception e) {
            log.error("为企业租户{}创建员工账号失败: {}", tenantId, e.getMessage(), e);
        }
    }

    @Override
    public Boolean rejectOffer(Long id, Long studentId) {
        MainBackCandidate candidate = mainBackCandidateMapper.selectById(id);
        if (candidate == null) {
            throw new ServiceException("候选记录不存在");
        }
        if (!candidate.getStudentId().equals(studentId)) {
            throw new ServiceException("无权操作该记录");
        }
        if (!"adopted".equals(candidate.getEnterpriseStatus())) {
            throw new ServiceException("企业未发出Offer");
        }
        if (!"pending".equals(candidate.getStudentStatus())) {
            throw new ServiceException("已处理过该Offer");
        }

        MainBackCandidate update = new MainBackCandidate();
        update.setId(id);
        update.setStudentStatus("rejected");
        update.setStudentReplyTime(LocalDateTime.now());
        // 同时更新旧status字段保持兼容
        update.setStatus("rejected");

        boolean rejected = mainBackCandidateMapper.updateById(update) > 0;
        if (rejected) {
            sendCandidateNotification(candidate, "投递进度更新", "您已拒绝Offer");
        }
        return rejected;
    }


    @Override
    public Boolean applyPosition(Long studentId, Long postId) {
        // 查询岗位信息获取 tenantId
        MainPosition position = mainPositionMapper.selectById(postId);
        if (position == null) {
            throw new ServiceException("岗位不存在");
        }

        // 检查是否已投递过
        LambdaQueryWrapper<MainBackCandidate> existsWrapper = new LambdaQueryWrapper<>();
        existsWrapper.eq(MainBackCandidate::getStudentId, studentId)
            .eq(MainBackCandidate::getPostId, postId)
            .eq(MainBackCandidate::getDelFlag, "0");
        Long count = mainBackCandidateMapper.selectCount(existsWrapper);
        if (count > 0) {
            throw new ServiceException("您已投递过该岗位");
        }

        // 创建候选记录
        MainBackCandidate candidate = new MainBackCandidate();
        candidate.setStudentId(studentId);
        candidate.setPostId(postId);
        candidate.setTenantId(position.getTenantId());
        candidate.setSource("student_apply");
        candidate.setEnterpriseStatus("pending");
        candidate.setStudentStatus("pending");
        candidate.setStatus("pending");

        boolean applied = mainBackCandidateMapper.insert(candidate) > 0;
        if (applied) {
            sendCandidateNotification(candidate, "投递进度更新", "您已成功投递岗位：" + position.getPostName());
        }
        return applied;
    }

    /**
     * 投递进度变化时发送通知消息给学员
     */
    private void sendCandidateNotification(MainBackCandidate candidate, String title, String content) {
        try {
            if (candidate == null || candidate.getStudentId() == null) return;
            mainMessageService.sendNotification(candidate.getStudentId(), title, content, candidate.getPostId());
        } catch (Exception e) {
            log.warn("投递进度变化发送通知消息失败，candidateId={}, error={}", candidate != null ? candidate.getId() : null, e.getMessage());
        }
    }
}
