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

import cn.hutool.core.codec.Base64;
import com.alibaba.excel.EasyExcel;
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.yuchen.saas.park.api.dto.pldoor.PlPropertyPassDTO;
import com.yuchen.saas.park.api.entity.park.PmgBatParkInfo;
import com.yuchen.saas.park.api.entity.pldoor.PlPropertyPass;
import com.yuchen.saas.park.api.entity.pldoor.PlPropertyPassImg;
import com.yuchen.saas.park.api.entity.pldoor.PlPropertyPassObject;
import com.yuchen.saas.park.api.entity.pldoor.PlVisitorInfo;
import com.yuchen.saas.park.api.entity.property.PropertyBuildingUnit;
import com.yuchen.saas.park.api.entity.property.PropertyBuildings;
import com.yuchen.saas.park.api.entity.property.PropertyBuildingsLevel;
import com.yuchen.saas.park.api.entity.property.PropertyHouses;
import com.yuchen.saas.park.api.enums.property.IdTypeEnum;
import com.yuchen.saas.park.api.enums.property.OwnerTypeEnum;
import com.yuchen.saas.park.api.vo.pldoor.PlPropertyPassVO;
import com.yuchen.saas.park.api.vo.pldoor.PlVisitorInfoVO;
import com.yuchen.saas.park.api.vo.property.PropertyHouseOwnerExcelVo;
import com.yuchen.saas.park.api.vo.property.PropertyHouseOwnerListVo;
import com.yuchen.saas.park.api.vo.property.PropertyHousesVo;
import com.yuchen.saas.park.api.vo.request.PlPropertyPassReq;
import com.yuchen.saas.park.service.mapper.pldoor.PlPropertyPassMapper;
import com.yuchen.saas.park.service.service.PmgBatParkInfoService;
import com.yuchen.saas.park.service.service.pldoor.PlPropertyPassImgService;
import com.yuchen.saas.park.service.service.pldoor.PlPropertyPassObjectService;
import com.yuchen.saas.park.service.service.pldoor.PlPropertyPassService;
import com.yuchen.saas.park.service.service.property.PropertyBuildingUnitService;
import com.yuchen.saas.park.service.service.property.PropertyBuildingsLevelService;
import com.yuchen.saas.park.service.service.property.PropertyBuildingsService;
import com.yuchen.saas.park.service.service.property.PropertyHousesService;
import com.yuchen.saas.park.service.util.EncryptUntil;
import org.nest.springwrap.core.mp.base.BaseServiceImpl;
import org.nest.springwrap.core.secure.ContextUser;
import org.nest.springwrap.core.secure.utils.AuthUtil;
import org.nest.springwrap.core.tool.utils.BeanUtil;
import org.nest.springwrap.core.tool.utils.Func;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 物品放行 服务实现类
 * </p>
 *
 * @author miaoqs
 * @since 2024-07-03
 */
@Service
public class PlPropertyPassServiceImpl extends BaseServiceImpl<PlPropertyPassMapper, PlPropertyPass> implements PlPropertyPassService {

    @Resource
    private PlPropertyPassObjectService plPropertyPassObjectService;
    @Resource
    private PlPropertyPassImgService PlPropertyPassImgService;
    @Resource
    private PlPropertyPassMapper plPropertyPassMapper;
    @Resource
    private PmgBatParkInfoService pmgBatParkInfoService;
    @Resource
    private PropertyBuildingsService propertyBuildingsService;
    @Resource
    private PropertyBuildingUnitService propertyBuildingUnitService;
    @Resource
    private PropertyBuildingsLevelService propertyBuildingsLevelService;
    @Resource
    private PropertyHousesService propertyHousesService;

    @Override
    public boolean saveOrUpdateByParam(PlPropertyPassDTO plPropertyPassDTO) {
        PlPropertyPass plPropertyPass = new PlPropertyPass();
        BeanUtil.copyProperties(plPropertyPassDTO,plPropertyPass);
        Long id = plPropertyPass.getId();
        plPropertyPass.setCheckInTime(new Date());
        saveOrUpdate(plPropertyPass);
        //移除原有数据
        if(Func.isNotEmpty(id)){
            plPropertyPassObjectService.remove(new LambdaQueryWrapper<PlPropertyPassObject>()
                    .eq(PlPropertyPassObject::getPlPropertyPassId, id));
            PlPropertyPassImgService.remove(new LambdaQueryWrapper<PlPropertyPassImg>()
                    .eq(PlPropertyPassImg::getPlPropertyPassId, id));
        }
        //新增物品
        if(Func.isNotEmpty(plPropertyPassDTO.getPlPropertyPassObjectList())){
            List<PlPropertyPassObject> plPropertyPassObjectList = plPropertyPassDTO.getPlPropertyPassObjectList();
            for (PlPropertyPassObject passObject : plPropertyPassObjectList) {
                passObject.setPlPropertyPassId(plPropertyPass.getId());
            }
            plPropertyPassObjectService.saveBatch(plPropertyPassObjectList);
        }
        //新增图片
        if(Func.isNotEmpty(plPropertyPassDTO.getPlPropertyPassImgList())){
            List<PlPropertyPassImg> passImgList = plPropertyPassDTO.getPlPropertyPassImgList();
            for (PlPropertyPassImg passImg : passImgList) {
                passImg.setPlPropertyPassId(plPropertyPass.getId());
            }
            PlPropertyPassImgService.saveBatch(passImgList);
        }
        return true;
    }

    @Override
    public PlPropertyPassVO detailById(Long id) {
        PlPropertyPassVO plPropertyPassVO = new PlPropertyPassVO();
        PlPropertyPass plPropertyPass = getById(id);
        BeanUtil.copyProperties(plPropertyPass,plPropertyPassVO);
        //物品
        List<PlPropertyPassObject> objectList = plPropertyPassObjectService.list(new LambdaQueryWrapper<PlPropertyPassObject>()
                .eq(PlPropertyPassObject::getPlPropertyPassId, id));
        if(Func.isNotEmpty(objectList)){
            plPropertyPassVO.setPlPropertyPassObjectList(objectList);
            //物品数量
            int objectNum = 0;
            for (PlPropertyPassObject passObject : objectList) {
                if(Func.isNotEmpty(passObject.getObjectNumber())){
                    objectNum += passObject.getObjectNumber();
                }
            }
            plPropertyPassVO.setObjectNum(objectNum);
        }
        //权限
        List<PlPropertyPassImg> imgList = PlPropertyPassImgService.list(new LambdaQueryWrapper<PlPropertyPassImg>()
                .eq(PlPropertyPassImg::getPlPropertyPassId, id));
        if(Func.isNotEmpty(imgList)){
            plPropertyPassVO.setPlPropertyPassImgList(imgList);
        }
        //房屋详细名称
        PmgBatParkInfo parkInfo = pmgBatParkInfoService.getById(plPropertyPass.getParkId());
        String roomAddress = (null == parkInfo?"":parkInfo.getParkName());
        PropertyBuildings buildings = propertyBuildingsService.getById(plPropertyPass.getBuildingId());
        roomAddress += (null == buildings?"":buildings.getBuildingName());
        PropertyBuildingUnit unit = propertyBuildingUnitService.getById(plPropertyPass.getElementId());
        roomAddress += (null == unit?"":unit.getUnitName());
        PropertyHouses houses = propertyHousesService.getById(plPropertyPass.getRoomNumberId());
        roomAddress += (null == houses?"":houses.getHouseName());
        plPropertyPassVO.setRoomAdress(roomAddress);
        return plPropertyPassVO;
    }

    @Override
    public boolean deleteById(Long id) {
        removeById(id);
        plPropertyPassObjectService.remove(new LambdaQueryWrapper<PlPropertyPassObject>()
                .eq(PlPropertyPassObject::getPlPropertyPassId, id));
        PlPropertyPassImgService.remove(new LambdaQueryWrapper<PlPropertyPassImg>()
                .eq(PlPropertyPassImg::getPlPropertyPassId, id));
        return true;
    }

    @Override
    public IPage<PlPropertyPassVO> pageByParam(Page<PlPropertyPassReq> page, PlPropertyPassReq req) {
        IPage<PlPropertyPassVO> PlPropertyPassVOIPage = plPropertyPassMapper.pageByParam(page, req);
        if(Func.isNotEmpty(PlPropertyPassVOIPage)){
            for (PlPropertyPassVO passVO : PlPropertyPassVOIPage.getRecords()) {
                passVO.setParkName(pmgBatParkInfoService.getById(passVO.getParkId()).getParkName());
                //房屋详细名称
                PmgBatParkInfo parkInfo = pmgBatParkInfoService.getById(passVO.getParkId());
                String roomAddress = (null == parkInfo?"":parkInfo.getParkName());
                PropertyBuildings buildings = propertyBuildingsService.getById(passVO.getBuildingId());
                roomAddress += (null == buildings?"":buildings.getBuildingName());
                PropertyBuildingUnit unit = propertyBuildingUnitService.getById(passVO.getElementId());
                roomAddress += (null == unit?"":unit.getUnitName());
                PropertyHouses houses = propertyHousesService.getById(passVO.getRoomNumberId());
                roomAddress += (null == houses?"":houses.getHouseName());
                passVO.setRoomAdress(roomAddress);

                List<PlPropertyPassObject> objectList = plPropertyPassObjectService.list(new LambdaQueryWrapper<PlPropertyPassObject>()
                        .eq(PlPropertyPassObject::getPlPropertyPassId, passVO.getId()));
                if(Func.isNotEmpty(objectList)){
                    int objectNum = 0;
                    for (PlPropertyPassObject passObject : objectList) {
                        if(Func.isNotEmpty(passObject.getObjectNumber())){
                            objectNum += passObject.getObjectNumber();
                        }
                    }
                    passVO.setObjectNum(objectNum);
                }
            }
        }
        return PlPropertyPassVOIPage;
    }

    @Override
    public void exportPropertyPass(PlPropertyPassReq req, HttpServletResponse response) {
        Page<PlPropertyPassReq> page = new Page<>(1, 100000);
        IPage<PlPropertyPassVO> PlPropertyPassVOIPage = plPropertyPassMapper.pageByParam(page, req);
        if(Func.isNotEmpty(PlPropertyPassVOIPage)){
            for (PlPropertyPassVO passVO : PlPropertyPassVOIPage.getRecords()) {
                passVO.setParkName(pmgBatParkInfoService.getById(passVO.getParkId()).getParkName());
                List<PlPropertyPassObject> objectList = plPropertyPassObjectService.list(new LambdaQueryWrapper<PlPropertyPassObject>()
                        .eq(PlPropertyPassObject::getPlPropertyPassId, passVO.getId()));
                if(Func.isNotEmpty(objectList)){
                    int objectNum = 0;
                    for (PlPropertyPassObject passObject : objectList) {
                        if(Func.isNotEmpty(passObject.getObjectNumber())){
                            objectNum += passObject.getObjectNumber();
                        }
                    }
                    passVO.setObjectNum(objectNum);
                }
                //房屋详细名称
                PmgBatParkInfo parkInfo = pmgBatParkInfoService.getById(passVO.getParkId());
                String roomAddress = (null == parkInfo?"":parkInfo.getParkName());
                PropertyBuildings buildings = propertyBuildingsService.getById(passVO.getBuildingId());
                roomAddress += (null == buildings?"":buildings.getBuildingName());
                PropertyBuildingUnit unit = propertyBuildingUnitService.getById(passVO.getElementId());
                roomAddress += (null == unit?"":unit.getUnitName());
                PropertyHouses houses = propertyHousesService.getById(passVO.getRoomNumberId());
                roomAddress += (null == houses?"":houses.getHouseName());
                passVO.setRoomAdress(roomAddress);
                String auditState = passVO.getAuditState();
                switch (auditState){
                    case "0":
                        passVO.setAuditStateStr("待审核");
                        break;
                    case "1":
                        passVO.setAuditStateStr("审核通过");
                        break;
                    case "2":
                        passVO.setAuditStateStr("审核不通过");
                        break;
                    case "3":
                        passVO.setAuditStateStr("已取消");
                        break;
                    default:
                        passVO.setAuditStateStr("");
                        break;
                }
            }
            List<PlPropertyPassVO> records = PlPropertyPassVOIPage.getRecords();
            try {
                String fileName = URLEncoder.encode("物品放行登记", "UTF-8").replaceAll("\\+", "%20");
                response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
                EasyExcel.write(response.getOutputStream(), PlPropertyPassVO.class)
                        .sheet("物品放行登记")
                        .doWrite(records); //最终处理好的数据结果集list
            } catch (IOException e) {
                log.error(e.getMessage(), e);
            }

        }

    }

    @Override
    public boolean updateState(PlPropertyPass plPropertyPass) {
        if(Func.isNotEmpty(plPropertyPass)){
            if(Func.isNotEmpty(plPropertyPass.getAuditState()) && plPropertyPass.getAuditState().equals("1")){
                plPropertyPass.setAuditTime(new Date());
                // 获取用户信息
                ContextUser contextUser = AuthUtil.getUser();
                plPropertyPass.setAuditUser(contextUser.getUserName());
                plPropertyPass.setAuditTime(new Date());
            }
            this.updateById(plPropertyPass);
        }
        return true;
    }

    @Override
    public String getPropertyPassQrcode(Long propertyPassId) throws UnsupportedEncodingException {
        if(Func.isNotEmpty(propertyPassId)){
            return cn.hutool.core.codec.Base64.encode(EncryptUntil.encrypt((propertyPassId.toString()).getBytes("utf-8")));
        }
        return null;
    }

    @Override
    public PlPropertyPassVO getPropertyPassByQrcode(PlPropertyPassVO plPropertyPassVO) throws Exception {
        if(Func.isNotEmpty(plPropertyPassVO) && Func.isNotEmpty(plPropertyPassVO.getPropertyPassQrcode())){
            byte[] bytes = Base64.decode(plPropertyPassVO.getPropertyPassQrcode());
            byte[] abc = EncryptUntil.decrypt(bytes);
            String propertyPassId = new String(abc);
            return this.detailById(Long.valueOf(propertyPassId));
        }
        return null;
    }

    @Override
    public IPage<PlPropertyPassVO> pageOpenDoorLog(Page<PlPropertyPassReq> page, PlPropertyPassReq req) {
        return null;
    }
}
