package com.ruoyi.web.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.web.controller.chenyanlogin.entity.HouseDigitalNumber;
import com.ruoyi.web.controller.chenyanlogin.entity.HousePicture;
import com.ruoyi.web.controller.chenyanlogin.service.IHouseDigitalNumberService;
import com.ruoyi.web.controller.chenyanlogin.service.IHousePictureService;
import com.ruoyi.web.domain.dto.house.HouseInfoAddRequest;
import com.ruoyi.web.domain.dto.house.HouseInfoEditRequest;
import com.ruoyi.web.domain.dto.house.HouseInfoQueryRequest;
import com.ruoyi.web.domain.entity.Event;
import com.ruoyi.web.domain.entity.HouseInfo;
import com.ruoyi.web.domain.entity.PersonHouseRelation;
import com.ruoyi.web.domain.entity.PersonInfo;
import com.ruoyi.web.domain.vo.HouseInfoByVo;
import com.ruoyi.web.domain.vo.HouseInfoVO;
import com.ruoyi.web.domain.vo.PersonInfoVO;
import com.ruoyi.web.mapper.HouseInfoMapper;
import com.ruoyi.web.service.EventService;
import com.ruoyi.web.service.HouseInfoService;
import com.ruoyi.web.service.PersonHouseRelationService;
import com.ruoyi.web.service.PersonInfoService;
import org.apache.poi.ss.formula.functions.Even;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 房屋服务
 */
@Service
public class HouseInfoServiceImpl extends ServiceImpl<HouseInfoMapper, HouseInfo>
        implements HouseInfoService {

    @Autowired
    private HouseInfoService houseInfoService;

    @Autowired
    private PersonHouseRelationService personHouseRelationService;

    @Autowired
    private PersonInfoService personInfoService;
    @Autowired
    private IHousePictureService housePictureService;
    @Autowired
    private IHouseDigitalNumberService houseDigitalNumberService;


    @Override
    public Long addHouseInfo(HouseInfoAddRequest houseInfoAddRequest) {
        if (houseInfoAddRequest == null) {
            throw new ServiceException("请求参数为空");
        }
        try {
            HouseInfo houseInfo = new HouseInfo();
            BeanUtil.copyProperties(houseInfoAddRequest, houseInfo);
            // 将标签 List 转为 String
            houseInfo.setHouseTags(JSONUtil.toJsonStr(houseInfoAddRequest.getHouseTags()));
            // 数据校验 todo
            validHouseInfo(houseInfo, BusinessType.INSERT);

            // 保存到数据库
            this.save(houseInfo);
            return houseInfo.getId();
        } catch (Exception e) {
            log.error("添加房屋失败", e);
            throw new ServiceException("添加房屋失败");
        }
    }

    @Override
    public boolean deleteHouseInfo(String ids) {
        if (StrUtil.isBlank(ids)) {
            throw new ServiceException("id不能为空或id异常");
        }

        // 2. 分割ID字符串为List<Integer>
        List<Long> idList = Arrays.stream(ids.split(","))
                .map(String::trim)
                .filter(StrUtil::isNotBlank)
                .map(Long::parseLong)
                .collect(Collectors.toList());

        if (idList.isEmpty()) {
            throw new ServiceException("ID格式异常");
        }

        // 3. 构建删除条件
        QueryWrapper<HouseInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("id", idList);

        // 4. 执行删除（返回是否删除成功）
        return remove(queryWrapper);
    }

    @Override
    public void editHouseInfo(HouseInfoEditRequest houseInfoEditRequest) {
        // 判断是否存在
        Integer id = houseInfoEditRequest.getId();
        HouseInfo oldHouseInfo = this.getById(id);
        if (oldHouseInfo == null) {
            throw new ServiceException("没有找到房屋");
        }
        HouseInfo houseInfo = new HouseInfo();
        BeanUtil.copyProperties(houseInfoEditRequest, houseInfo);
        // 将人口标签 List 转为 String
        houseInfo.setHouseTags(JSONUtil.toJsonStr(houseInfoEditRequest.getHouseTags()));
        houseInfo.setUpdateTime(new Date());
        // 数据校验
        validHouseInfo(houseInfo, BusinessType.UPDATE);
        // 操作数据库
        boolean result = this.updateById(houseInfo);
        if (!result) {
            throw new ServiceException("修改房屋操作失败");
        }
    }

    /**
     * 校验房屋
     *
     * @param houseInfo
     */
    public void validHouseInfo(HouseInfo houseInfo, BusinessType type) {
        if (ObjectUtil.isEmpty(houseInfo)) {
            throw new ServiceException("数据为空");
        }
        Long id = houseInfo.getId();
        String houseCode = houseInfo.getHouseCode();
        String doorplateNumber = houseInfo.getDoorplateNumber();
        String houseAddress = houseInfo.getHouseAddress();
        Long houseOwnerId = houseInfo.getHouseOwnerId();
        BigDecimal totalPoints = houseInfo.getTotalPoints();
        BigDecimal remainingPoints = houseInfo.getRemainingPoints();
        String houseCategory = houseInfo.getHouseCategory();
        String buildingArea = houseInfo.getBuildingArea();
        String grid = houseInfo.getGrid();
        String photoUrl = houseInfo.getPhotoUrl();
        String houseTags = houseInfo.getHouseTags();
        Date createTime = houseInfo.getCreateTime();
        Date updateTime = houseInfo.getUpdateTime();
        String delFlag = houseInfo.getDelFlag();


        // 修改数据时，id 不能为空 todo
        if (type != BusinessType.INSERT && ObjectUtil.isEmpty(id)) {
            throw new ServiceException("id不能为空");
        }
        if (StrUtil.isBlank(houseCode)) {
            throw new ServiceException("房屋编号不能为空");
        }
    }

    /**
     * 获取房屋包装类
     *
     * @param houseInfo
     * @return
     */
    @Override
    public HouseInfoVO getHouseInfoVO(HouseInfo houseInfo) {
        if (ObjectUtil.isEmpty(houseInfo)) {
            throw new ServiceException("请求参数不存在");
        }
        HouseInfoVO houseInfoVO = new HouseInfoVO();
        BeanUtils.copyProperties(houseInfo, houseInfoVO);

        // 通过关联表 获取 成员数量
        Long houseInfoId = houseInfo.getId();
        Integer memberCount = personHouseRelationService.lambdaQuery()
                .eq(PersonHouseRelation::getHouseId, houseInfoId)
                .count()
                .intValue();
        houseInfoVO.setMemberCount(memberCount);

        // 通过房主人员ID -> 房主姓名 身份证 联系方式(人员VO类)
        Long houseOwnerId = houseInfo.getHouseOwnerId();
        if (houseOwnerId != null) {
            PersonInfo houseOwnerInfo = personInfoService.getById(houseOwnerId);
            PersonInfoVO houseOwnerInfoVO = personInfoService.getPersonInfoVO(houseOwnerInfo);
            houseOwnerInfoVO.setHouseOwnerName(houseOwnerInfo.getRealname());
            houseOwnerInfoVO.setHouseCode(houseInfo.getHouseCode());
            houseOwnerInfoVO.setDoorplateNumber(houseInfo.getDoorplateNumber());
            houseInfoVO.setHouseOwnerInfo(houseOwnerInfoVO);
        }
        return houseInfoVO;
    }

    /**
     * 根据id获取人员包装类
     *
     * @param id
     * @return
     */
    @Override
    public HouseInfoVO getHouseInfoById(int id) {
        if (id <= 0 || ObjectUtil.isEmpty(id)) {
            throw new ServiceException("id不能为空或id异常");
        }
        HouseInfo houseInfo = this.getById(id);
        return getHouseInfoVO(houseInfo);
    }


    /**
     * 分页获取房屋列表
     *
     * @param houseInfoQueryRequest
     * @return
     */
    @Override
    public Page<HouseInfoVO> getListHouseInfoByPage(HouseInfoQueryRequest houseInfoQueryRequest) {
        long current = houseInfoQueryRequest.getPageNum();
        long size = houseInfoQueryRequest.getPageSize();
        // 1. 分页查询房屋基础信息
        Page<HouseInfo> houseInfoPage = this.page(new Page<>(current, size),
                getQueryWrapper(houseInfoQueryRequest));

        // 2. 补充关联数据
        Page<HouseInfoVO> resultPage = new Page<>();
        BeanUtils.copyProperties(houseInfoPage, resultPage, "records");

        // 3. 处理每条记录
        List<HouseInfoVO> viewList = houseInfoPage.getRecords().stream().map(houseInfo -> {
            return getHouseInfoVO(houseInfo);
        }).collect(Collectors.toList());
        resultPage.setRecords(viewList);
        return resultPage;
    }


    /**
     * 获取查询条件
     *
     * @param houseInfoQueryRequest
     * @return
     */
    @Override
    public QueryWrapper<HouseInfo> getQueryWrapper(HouseInfoQueryRequest houseInfoQueryRequest) {
        QueryWrapper<HouseInfo> queryWrapper = new QueryWrapper<>();
        if (houseInfoQueryRequest == null) {
            return queryWrapper;
        }

        // 从对象中取值
        Integer id = houseInfoQueryRequest.getId();
        String doorplateNumber = houseInfoQueryRequest.getDoorplateNumber();
        Integer houseOwnerId = houseInfoQueryRequest.getHouseOwnerId();
        String houseOwnerName = houseInfoQueryRequest.getHouseOwnerName();
        String houseCategory = houseInfoQueryRequest.getHouseCategory();
        Integer grid = houseInfoQueryRequest.getGrid();
        List<String> houseTags = houseInfoQueryRequest.getHouseTags();
        String sortField = houseInfoQueryRequest.getSortField();
        String sortOrder = houseInfoQueryRequest.getSortOrder();

        //门牌号、房主ID、房屋类别、所属网格、家庭标签
        queryWrapper.eq(ObjectUtil.isNotEmpty(id), "id", id);
        queryWrapper.like(StrUtil.isNotBlank(doorplateNumber), "doorplate_number", doorplateNumber);
        //queryWrapper.eq(ObjectUtil.isNotEmpty(houseOwnerId), "house_owner_id", houseOwnerId);
        queryWrapper.eq(ObjectUtil.isNotEmpty(grid), "grid", grid);
        queryWrapper.eq(StrUtil.isNotBlank(houseCategory), "house_category", houseCategory);

        // 优先使用 房主id 查询  没有房主id 再根据 房主姓名查询
        if (ObjectUtil.isNotEmpty(houseOwnerId)) {
            queryWrapper.eq("house_owner_id", houseOwnerId);
        } else if (StrUtil.isNotBlank(houseOwnerName)) {
            queryWrapper.exists("EXISTS (SELECT 1 FROM person_info p WHERE p.id = house_owner_id AND p.realname LIKE {0})");
        }

        // 家庭标签 JSON 数组查询
        if (CollUtil.isNotEmpty(houseTags)) {
            for (String tag : houseTags) {
                queryWrapper.like("house_tags", "\"" + tag + "\"");
            }
        }

        // 排序
        queryWrapper.orderBy(StrUtil.isNotEmpty(sortField), "ascend".equals(sortOrder), sortField);
        return queryWrapper;
    }

    @Override
    public HouseInfoByVo getHouseInfoBy(Integer id) {
        HouseInfo byId = this.getById(id);
        HouseInfoByVo houseInfoVO = new HouseInfoByVo();
        if (ObjectUtil.isNotEmpty(byId)){
            houseInfoVO.setDoorplateNumber(byId.getDoorplateNumber());
            houseInfoVO.setGrid(byId.getGrid());
            houseInfoVO.setHouseAddress(byId.getHouseAddress());
            houseInfoVO.setTags(byId.getHouseTags());
            //房主名字
            PersonInfo personInfo = personInfoService.getById(byId.getHouseOwnerId());
            if (ObjectUtil.isNotEmpty(personInfo)){
                houseInfoVO.setOwnerName(personInfo.getRealname());
            }
            //成员名字
            houseInfoVO.setMemberName(personHouseRelationService.getName(id));
            //图片
            List<HousePicture> housePictures = housePictureService.list(new QueryWrapper<HousePicture>().eq("house_id", id));
            for (HousePicture picture : housePictures) {
                if (ObjectUtil.isNotEmpty(picture)){
                    houseInfoVO.setHousePicture(picture.getPicture());
                }
            }
            //二维码
            List<HouseDigitalNumber> houseDigitalNumbers = houseDigitalNumberService.list(new QueryWrapper<HouseDigitalNumber>().eq("house_id", id).eq("type",0));
            for (HouseDigitalNumber houseDigitalNumber : houseDigitalNumbers) {
                if (ObjectUtil.isNotEmpty(houseDigitalNumber)){
                    houseInfoVO.setQrCode(houseDigitalNumber.getNumberPlateUrl());
                }
            }

            //事件
            houseInfoVO.setEvents(getEvent(id));
            houseInfoVO.setGeoData(byId.getGeoData());

        }


        return houseInfoVO;
    }

    @Override
    public String saveGeoData(Map<String, Object> map) {
        int id = (Integer)map.get("id");
        String geoData = (String)map.get("geoData");
        HouseInfo houseInfo = new HouseInfo();
        houseInfo.setId((long) id);
        houseInfo.setGeoData(geoData);
        this.updateById(houseInfo);

        return null;
    }

    @Autowired
    private EventService eventService;

    private List<Event> getEvent(Integer id) {
        List<PersonHouseRelation> personHouseRelations = personHouseRelationService.list(new QueryWrapper<PersonHouseRelation>().eq("house_id", id));
        if (ObjectUtil.isNotEmpty(personHouseRelations)){
            List<Long> collect = personHouseRelations.stream().map(PersonHouseRelation::getPersonId).collect(Collectors.toList());
            List<Event> submitter_id = eventService.list(new QueryWrapper<Event>().in("submitter_id", collect));
            for (Event event : submitter_id) {
                event.setSubmitterName(personInfoService.getById(event.getSubmitterId()).getRealname());
            }
            return submitter_id;
        }
        return new ArrayList<>();

    }
}




