package com.yuchen.saas.park.service.service.property.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yuchen.saas.integration.feign.api.util.PageConverterUtils;
import com.yuchen.saas.manage.user.api.entity.UserDetail;
import com.yuchen.saas.manage.user.api.feign.IUserClient;
import com.yuchen.saas.park.api.dto.property.*;
import com.yuchen.saas.park.api.entity.park.PmgBatParkInfo;
import com.yuchen.saas.park.api.entity.property.PropertyAppointHouse;
import com.yuchen.saas.park.api.entity.property.PropertyAppointHouseRecord;
import com.yuchen.saas.park.api.enums.PropertyAppointStatusEnum;
import com.yuchen.saas.park.api.vo.property.*;
import com.yuchen.saas.park.service.mapper.property.PropertyAppointHouseMapper;
import com.yuchen.saas.park.service.service.PmgBatParkInfoService;
import com.yuchen.saas.park.service.service.property.IPropertyAppointHouseRecordService;
import com.yuchen.saas.park.service.service.property.IPropertyAppointHouseService;
import org.nest.springwrap.core.log.exception.ServiceException;
import org.nest.springwrap.core.mp.base.BaseServiceImpl;
import org.nest.springwrap.core.mp.support.NestPage;
import org.nest.springwrap.core.secure.ContextUser;
import org.nest.springwrap.core.secure.utils.AuthUtil;
import org.nest.springwrap.core.tool.api.R;
import org.nest.springwrap.core.tool.utils.BeanUtil;
import org.nest.springwrap.core.tool.utils.Func;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author 蔡文强
 * @Date 2023/10/27 10:56
 * @Description 预约看房主表 服务实现类
 */
@Service
public class PropertyAppointHouseServiceImpl extends BaseServiceImpl<PropertyAppointHouseMapper, PropertyAppointHouse> implements IPropertyAppointHouseService {

    @Resource
    private IPropertyAppointHouseRecordService appointHouseRecordService;

    @Resource
    private PmgBatParkInfoService pmgBatParkInfoService;

    @Resource
    private IUserClient userClient;

    @Override
    public Boolean submitIntention(PropertyAppointHouseSubmitIntentionDTO submitIntentionDTO) {
        PropertyAppointHouse appointHouse = BeanUtil.copyProperties(submitIntentionDTO, PropertyAppointHouse.class);
        ContextUser contextUser = AuthUtil.getUser();
        if (Func.isEmpty(contextUser)) {
            throw new ServiceException("用户不存在");
        }
        Long userDetailId = contextUser.getUserDetailId();
        appointHouse.setUserDetailId(userDetailId);
        return save(appointHouse);
    }

    @Override
    public Boolean confirmIntention(PropertyAppointHouseConfirmIntentionDTO confirmIntentionDTO) {
        PropertyAppointHouse appointHouse = BeanUtil.copyProperties(confirmIntentionDTO, PropertyAppointHouse.class);
        ContextUser contextUser = AuthUtil.getUser();
        if (Func.isEmpty(contextUser)) {
            throw new ServiceException("用户不存在");
        }
        Long confirmPeopleId = contextUser.getUserDetailId();
        appointHouse.setConfirmPeopleId(confirmPeopleId);
        R<UserDetail> userDetailR = userClient.userDetailById(confirmPeopleId);
        if (userDetailR.isSuccess() && Func.isNotEmpty(userDetailR.getData())) {
            appointHouse.setUpdateUserName(userDetailR.getData().getName());
        }
        appointHouse.setConfirmTime(new Date());
        if (confirmIntentionDTO.getConfirmResult() == 1) {
            appointHouse.setAppointStatus(PropertyAppointStatusEnum.PUT_INTO_INTENTION.getValue());
        }
        if (confirmIntentionDTO.getConfirmResult() == 2) {
            appointHouse.setAppointStatus(PropertyAppointStatusEnum.NO_APPOINT.getValue());
        }
        return updateById(appointHouse);
    }

    @Override
    public PropertyAppointHouseIntentionDetailVO getIntentionDetailById(Long id) {
        PropertyAppointHouse appointHouse = getById(id);
        PropertyAppointHouseIntentionDetailVO appointHouseIntentionDetailVO = BeanUtil.copyProperties(appointHouse, PropertyAppointHouseIntentionDetailVO.class);
        PmgBatParkInfo parkInfo = pmgBatParkInfoService.getById(appointHouse.getParkId());
        appointHouseIntentionDetailVO.setParkName(parkInfo.getParkName());
        R<UserDetail> userDetailR = userClient.userDetailById(appointHouse.getConfirmPeopleId());
        if (userDetailR.isSuccess() && Func.isNotEmpty(userDetailR.getData())) {
            appointHouseIntentionDetailVO.setConfirmPeopleName(userDetailR.getData().getName() + "(" + userDetailR.getData().getPhone() + ")");
        }
        return appointHouseIntentionDetailVO;
    }

    @Override
    public NestPage<PropertyAppointHouseIntentionPcListVO> getPcIntentionList(PropertyAppointHouseIntentionPcListQueryDTO queryDTO) {
        // 分页获取数据
        Page<PropertyAppointHouseIntentionPcListVO> page = new Page<>(queryDTO.getCurrent(), queryDTO.getSize());
        page = baseMapper.getPcIntentionList(page, queryDTO);
        List<PropertyAppointHouseIntentionPcListVO> list = page.getRecords();
        if (Func.isNotEmpty(list)) {
            List<Long> userDetailIds = list.stream().map(PropertyAppointHouseIntentionPcListVO::getUserDetailId).filter(Objects::nonNull).collect(Collectors.toList());
            Map<Long, String> userNameMap = new HashMap<>();
            R<List<UserDetail>> userDetailResult = userClient.listUserDetailByIds(userDetailIds);
            if (userDetailResult.isSuccess() && Func.isNotEmpty(userDetailResult.getData())) {
                userNameMap = userDetailResult.getData().stream().collect((Collectors.toMap(UserDetail::getId, UserDetail::getName, (v1, v2) -> v2)));
            }
            for (PropertyAppointHouseIntentionPcListVO vo : list) {
                vo.setCreateUserName(String.valueOf(userNameMap.get(vo.getUserDetailId())));
            }
            page.setRecords(list);
        }
        return PageConverterUtils.convert(page);
    }

    @Override
    public NestPage<PropertyAppointHouseIntentionAppListVO> getAppIntentionList(PropertyAppointHouseIntentionAppListQueryDTO queryDTO) {
        // 分页获取数据
        Page<PropertyAppointHouseIntentionAppListVO> page = new Page<>(queryDTO.getCurrent(), queryDTO.getSize());
        page = baseMapper.getAppIntentionList(page, queryDTO);
        return PageConverterUtils.convert(page);
    }

    @Override
    public Boolean createAppoint(PropertyAppointHouseCreateAppointDTO createAppointDTO) {
        PropertyAppointHouse appointHouse = BeanUtil.copyProperties(createAppointDTO.getAppointHouseIntention(), PropertyAppointHouse.class);
        appointHouse.setConfirmResult(2);
        appointHouse.setAppointStatus(PropertyAppointStatusEnum.NO_REVIEWED.getValue());
        appointHouse.setUserDetailId(0L);
        save(appointHouse);
        Long masterId = appointHouse.getId();
        PropertyAppointHouseRecord appointHouseRecord = BeanUtil.copyProperties(createAppointDTO.getAppointHouseRegister(), PropertyAppointHouseRecord.class);
        appointHouseRecord.setMasterId(masterId);
        ContextUser contextUser = AuthUtil.getUser();
        if (Func.isEmpty(contextUser)) {
            throw new ServiceException("用户不存在");
        }
        Long userDetailId = contextUser.getUserDetailId();
        appointHouseRecord.setRegisterPeopleId(userDetailId);
        appointHouseRecord.setRegisterTime(new Date());
        return appointHouseRecordService.save(appointHouseRecord);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean appointRegister(PropertyAppointHouseRegisterDTO registerDTO) {
        PropertyAppointHouse propertyAppointHouse = getById(registerDTO.getMasterId());
        if (Func.isEmpty(propertyAppointHouse)) {
            throw new ServiceException("预约看房主表记录不存在");
        }
        ContextUser contextUser = AuthUtil.getUser();
        if (Func.isEmpty(contextUser)) {
            throw new ServiceException("用户不存在");
        }
        Long userDetailId = contextUser.getUserDetailId();
        R<UserDetail> userDetailR = userClient.userDetailById(userDetailId);
        if (userDetailR.isSuccess() && Func.isNotEmpty(userDetailR.getData())) {
            propertyAppointHouse.setUpdateUserName(userDetailR.getData().getName());
        }
        propertyAppointHouse.setAppointStatus(PropertyAppointStatusEnum.NO_REVIEWED.getValue());
        updateById(propertyAppointHouse);
        PropertyAppointHouseRecord isLatestHouseRecord = appointHouseRecordService.lambdaQuery().eq(PropertyAppointHouseRecord::getMasterId, registerDTO.getMasterId()).eq(PropertyAppointHouseRecord::getIsLatest, 1).one();
        if(Func.isNotEmpty(isLatestHouseRecord)) {
            isLatestHouseRecord.setIsLatest(0);
            appointHouseRecordService.updateById(isLatestHouseRecord);
        }
        PropertyAppointHouseRecord appointHouseRecord = BeanUtil.copyProperties(registerDTO, PropertyAppointHouseRecord.class);
        appointHouseRecord.setRegisterPeopleId(userDetailId);
        appointHouseRecord.setRegisterTime(new Date());
        return appointHouseRecordService.save(appointHouseRecord);
    }


    @Override
    public Boolean reviewRegister(PropertyAppointHouseReviewRegisterDTO reviewRegisterDTO) {
        PropertyAppointHouse propertyAppointHouse = getById(reviewRegisterDTO.getId());
        if (Func.isEmpty(propertyAppointHouse)) {
            throw new ServiceException("预约看房主表记录不存在");
        }
        ContextUser contextUser = AuthUtil.getUser();
        if (Func.isEmpty(contextUser)) {
            throw new ServiceException("用户不存在");
        }
        Long updateUser = contextUser.getUserDetailId();
        R<UserDetail> userDetailR = userClient.userDetailById(updateUser);
        if (userDetailR.isSuccess() && Func.isNotEmpty(userDetailR.getData())) {
            propertyAppointHouse.setUpdateUserName(userDetailR.getData().getName());
        }
        propertyAppointHouse.setAppointStatus(PropertyAppointStatusEnum.REVIEWED.getValue());
        propertyAppointHouse.setLookResult(reviewRegisterDTO.getLookResult());
        propertyAppointHouse.setRemark(reviewRegisterDTO.getRemark());
        return updateById(propertyAppointHouse);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean appointCancel(PropertyAppointHouseCancelDTO cancelDTO) {
        PropertyAppointHouseRecord appointHouseRecord = appointHouseRecordService.getById(cancelDTO.getRecordId());
        if (Func.isEmpty(appointHouseRecord)) {
            throw new ServiceException("预约记录不存在");
        }
        PropertyAppointHouse appointHouse = getById(appointHouseRecord.getMasterId());
        if (Func.isEmpty(appointHouse)) {
            throw new ServiceException("预约看房主表记录不存在");
        }
        appointHouse.setAppointStatus(cancelDTO.getCancelType() == 1 ? PropertyAppointStatusEnum.CANCEL_REAPPLY.getValue() : PropertyAppointStatusEnum.CANCEL_NO_NEED.getValue());
        ContextUser contextUser = AuthUtil.getUser();
        if (Func.isEmpty(contextUser)) {
            throw new ServiceException("用户不存在");
        }
        Long cancelPeopleId = contextUser.getUserDetailId();
        R<UserDetail> userDetailR = userClient.userDetailById(cancelPeopleId);
        if (userDetailR.isSuccess() && Func.isNotEmpty(userDetailR.getData())) {
            appointHouse.setUpdateUserName(userDetailR.getData().getName());
        }
        updateById(appointHouse);
        appointHouseRecord.setCancelType(cancelDTO.getCancelType());
        appointHouseRecord.setCancelRemark(cancelDTO.getCancelRemark());
        appointHouseRecord.setCancelPeopleId(cancelPeopleId);
        appointHouseRecord.setCancelTime(new Date());
        return appointHouseRecordService.updateById(appointHouseRecord);
    }

    @Override
    public NestPage<PropertyAppointHousePcListVO> getPcAppointList(PropertyAppointHousePcListQueryDTO queryDTO) {
        // 分页获取数据
        Page<PropertyAppointHousePcListVO> page = new Page<>(queryDTO.getCurrent(), queryDTO.getSize());
        page = baseMapper.getPcAppointList(page, queryDTO);
        return PageConverterUtils.convert(page);
    }

    @Override
    public NestPage<PropertyAppointHouseAppListVO> getAppAppointList(PropertyAppointHouseAppListQueryDTO queryDTO) {
        // 分页获取数据
        Page<PropertyAppointHouseAppListVO> page = new Page<>(queryDTO.getCurrent(), queryDTO.getSize());
        page = baseMapper.getAppAppointList(page, queryDTO);
        return PageConverterUtils.convert(page);
    }

    @Override
    public NestPage<PropertyAppointHouseAppListVO> getMyAppointList(PropertyAppointHouseAppListQueryDTO queryDTO) {
        // 分页获取数据
        Page<PropertyAppointHouseAppListVO> page = new Page<>(queryDTO.getCurrent(), queryDTO.getSize());
        page = baseMapper.getAppAppointList(page, queryDTO);
        return PageConverterUtils.convert(page);
    }

    @Override
    public PropertyAppointHouseDetailVO getAppointDetailById(Long id) {
        PropertyAppointHouseDetailVO appointHouseDetailVO = BeanUtil.copyProperties(getById(id), PropertyAppointHouseDetailVO.class);
        PmgBatParkInfo parkInfo = pmgBatParkInfoService.getById(appointHouseDetailVO.getParkId());
        appointHouseDetailVO.setParkName(parkInfo.getParkName());
        R<UserDetail> userDetailR = userClient.userDetailById(appointHouseDetailVO.getConfirmPeopleId());
        if (userDetailR.isSuccess() && Func.isNotEmpty(userDetailR.getData())) {
            appointHouseDetailVO.setConfirmPeopleName(userDetailR.getData().getName());
        }
        List<PropertyAppointHouseRecord> list = appointHouseRecordService.lambdaQuery().eq(PropertyAppointHouseRecord::getMasterId, id).orderByDesc(PropertyAppointHouseRecord::getCreateTime).list();
        List<PropertyAppointHouseRecordVO> houseRecordList = new ArrayList<>();
        if (Func.isNotEmpty(list)) {
            houseRecordList = BeanUtil.copyProperties(list, PropertyAppointHouseRecordVO.class);
            List<Long> registerPeopleIds = houseRecordList.stream().map(PropertyAppointHouseRecordVO::getRegisterPeopleId).filter(Objects::nonNull).collect(Collectors.toList());
            List<Long> cancelPeopleIds = houseRecordList.stream().map(PropertyAppointHouseRecordVO::getCancelPeopleId).filter(Objects::nonNull).collect(Collectors.toList());
            List<Long> userDetailIds = new ArrayList<>();
            userDetailIds.addAll(registerPeopleIds);
            userDetailIds.addAll(cancelPeopleIds);
            Map<Long, String> userNameMap = new HashMap<>();
            R<List<UserDetail>> userDetailResult = userClient.listUserDetailByIds(userDetailIds);
            if (userDetailResult.isSuccess() && Func.isNotEmpty(userDetailResult.getData())) {
                userNameMap = userDetailResult.getData().stream().collect((Collectors.toMap(UserDetail::getId, UserDetail::getName, (v1, v2) -> v2)));
            }
            for (PropertyAppointHouseRecordVO vo : houseRecordList) {
                vo.setRegisterPeopleName(String.valueOf(userNameMap.get(vo.getRegisterPeopleId())));
                vo.setCancelPeopleName(String.valueOf(userNameMap.get(vo.getCancelPeopleId())));
            }
        }
        appointHouseDetailVO.setAppointHouseRecordList(houseRecordList);
        return appointHouseDetailVO;
    }

    @Override
    public PropertyAppointHouseMyDetailVO getMyAppointDetailById(Long id) {
        PropertyAppointHouseMyDetailVO appointHouseMyDetailVO = BeanUtil.copyProperties(getById(id), PropertyAppointHouseMyDetailVO.class);
        PmgBatParkInfo parkInfo = pmgBatParkInfoService.getById(appointHouseMyDetailVO.getParkId());
        appointHouseMyDetailVO.setParkName(parkInfo.getParkName());
        List<PropertyAppointHouseRecord> list = appointHouseRecordService.lambdaQuery().eq(PropertyAppointHouseRecord::getMasterId, id).orderByDesc(PropertyAppointHouseRecord::getCreateTime).list();
        if (Func.isNotEmpty(list)) {
            List<PropertyAppointHouseMyRecordVO> appointHouseRecordList = BeanUtil.copyProperties(list, PropertyAppointHouseMyRecordVO.class);
            appointHouseMyDetailVO.setAppointHouseRecordList(appointHouseRecordList);
        }
        return appointHouseMyDetailVO;
    }

}
