package com.ruoyi.zdsz.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.framework.obs.FileUtil;
import com.ruoyi.system.mapper.SysDictDataMapper;
import com.ruoyi.zdsz.domain.*;
import com.ruoyi.zdsz.domain.vo.GExportsVo;
import com.ruoyi.zdsz.domain.vo.GImportVo;
import com.ruoyi.zdsz.mapper.ZBuildingMapper;
import com.ruoyi.zdsz.mapper.ZHouseMapper;
import com.ruoyi.zdsz.mapper.ZUnitMapper;
import com.ruoyi.zdsz.service.IZBuildingService;
import lombok.RequiredArgsConstructor;
import org.mybatis.logging.Logger;
import org.mybatis.logging.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.ruoyi.zdsz.domain.bo.ZAreaBo;
import com.ruoyi.zdsz.domain.vo.ZAreaVo;
import com.ruoyi.zdsz.mapper.ZAreaMapper;
import com.ruoyi.zdsz.service.IZAreaService;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 小区管理Service业务层处理
 *
 * @author ruoyi
 * @date 2023-12-27
 */
@RequiredArgsConstructor
@Service
public class ZAreaServiceImpl implements IZAreaService {

    private static final Logger logger = LoggerFactory.getLogger(ZAreaServiceImpl.class);

    @Value("${filePath}")
    private String path;

    @Resource
    private ZAreaMapper baseMapper;
    @Resource
    private ZBuildingMapper zBuildingMapper;
    @Resource
    private ZUnitMapper zUnitMapper;
    @Resource
    private ZHouseMapper zHouseMapper;

    @Resource
    private SysDictDataMapper sysDictDataMapper;

    @Override
    public List<GImportVo> selectList(ZAreaBo bo) {
        return baseMapper.selectGExportsList(bo);
    }

    @Override
    public Map<String, Object> importUser(List<GImportVo> list, Boolean isUpdateSupport, String operName, int n, int successNum) {
        if (ObjectUtils.isEmpty(list) || list.size() == 0) {
            throw new ServiceException("导入数据不能为空！");
        }
        Map<String, Object> ret = new HashMap<>();
        StringBuilder successMsg = new StringBuilder();
        for (int i = n; i < list.size(); i++) {
            GImportVo vo = list.get(i);
            String districtValue = sysDictDataMapper.queryValueTextByKey("district", vo.getDistrict());
            String sourceValue = sysDictDataMapper.queryValueTextByKey("community_source", vo.getSource());
            if (StringUtils.isBlank(districtValue)) {
                throw new ServiceException("" + "第" + (n + 1) + "行行政区填写错误,导入失败!");
            }
            if (StringUtils.isBlank(sourceValue)) {
                throw new ServiceException("" + "第" + (n + 1) + "行来源填写错误,导入失败!");
            }
            try {
                n++;
                // 验证是否存在这个小区
                if (StringUtils.isNotEmpty(vo.getAreaName())) {
                    ZArea area = baseMapper.getByName(vo.getAreaName());
                    ZBuilding building = new ZBuilding();
                    ZUnit unit = new ZUnit();
                    ZHouse house = new ZHouse();
                    if (ObjectUtils.isEmpty(area)) {
                        area = new ZArea();
                        //小区zDsZ1a2b3c4d%1234!
                        area.setName(vo.getAreaName());
                        area.setCreateBy(operName);
                        area.setCreateTime(new Date());
                        area.setDistrict(districtValue);
                        area.setSource(sourceValue);
                        area.setAdministrative(vo.getAdministrative());
                        area.setRenovationColumn("Y");
                        baseMapper.insert(area);
                        if (StringUtils.isNotEmpty(vo.getBuildName())) {
                            //楼宇
                            building.setName(vo.getBuildName());
                            building.setAreaId(area.getId());
                            building.setCreateBy(operName);
                            building.setCreateTime(new Date());
                            building.setSource(sourceValue);
                            zBuildingMapper.insert(building);
                            if (StringUtils.isNotEmpty(vo.getUnitName())) {
                                //单元
                                unit.setName(vo.getUnitName());
                                unit.setBuildingId(building.getId());
                                unit.setAreaId(area.getId());
                                unit.setCreateBy(operName);
                                unit.setCreateTime(new Date());
                                unit.setSource(sourceValue);
                                zUnitMapper.insert(unit);
                                if (StringUtils.isNotEmpty(vo.getHouseName())) {
                                    //房屋
                                    house.setName(vo.getHouseName());
                                    house.setAreaId(area.getId());
                                    house.setBuildingId(building.getId());
                                    house.setUnitId(unit.getId());
                                    house.setCreateBy(operName);
                                    house.setCreateTime(new Date());
                                    house.setSource(sourceValue);
                                    house.setHouseUserName(vo.getHouseUserName());
                                    house.setIdCard(vo.getIdCard());
                                    house.setPhone(vo.getPhone());
                                    zHouseMapper.insert(house);
                                    successNum++;
                                } else {
                                    throw new ServiceException("" + "第" + (n + 1) + "行格式错误,导入失败!");
                                }
                            } else {
                                throw new ServiceException("" + "第" + (n + 1) + "行格式错误,导入失败!");
                            }
                        } else {
                            throw new ServiceException("" + "第" + (n + 1) + "行格式错误,导入失败!");
                        }
                    } else if (isUpdateSupport) {
                        //小区zDsZ1a2b3c4d%1234!
                        area.setCreateBy(operName);
                        area.setCreateTime(new Date());
                        area.setDistrict(districtValue);
                        area.setSource(sourceValue);
                        area.setAdministrative(vo.getAdministrative());
                        area.setRenovationColumn("Y");
                        baseMapper.updateById(area);
                        if (StringUtils.isNotEmpty(vo.getBuildName())) {
                            building = zBuildingMapper.getByName(vo.getBuildName(), area.getId());
                            if (ObjectUtils.isEmpty(building)) {
                                building = new ZBuilding();
                                //楼宇
                                building.setName(vo.getBuildName());
                                building.setAreaId(area.getId());
                                building.setCreateBy(operName);
                                building.setCreateTime(new Date());
                                building.setSource(sourceValue);
                                zBuildingMapper.insert(building);
                                if (StringUtils.isNotEmpty(vo.getUnitName())) {
                                    //单元
                                    unit.setName(vo.getUnitName());
                                    unit.setAreaId(area.getId());
                                    unit.setBuildingId(building.getId());
                                    unit.setCreateBy(operName);
                                    unit.setCreateTime(new Date());
                                    unit.setSource(sourceValue);
                                    zUnitMapper.insert(unit);
                                    if (StringUtils.isNotEmpty(vo.getHouseName())) {
                                        //房屋
                                        house.setName(vo.getHouseName());
                                        house.setAreaId(area.getId());
                                        house.setBuildingId(building.getId());
                                        house.setUnitId(unit.getId());
                                        house.setCreateBy(operName);
                                        house.setCreateTime(new Date());
                                        house.setSource(sourceValue);
                                        house.setHouseUserName(vo.getHouseUserName());
                                        house.setIdCard(vo.getIdCard());
                                        house.setPhone(vo.getPhone());
                                        zHouseMapper.insert(house);
                                        successNum++;
                                    } else {
                                        throw new ServiceException("" + "第" + (n + 1) + "行格式错误,导入失败!");
                                    }
                                } else {
                                    throw new ServiceException("" + "第" + (n + 1) + "行格式错误,导入失败!");
                                }
                            } else {
                                building.setAreaId(area.getId());
                                building.setUpdateBy(operName);
                                building.setUpdateTime(new Date());
                                building.setSource(sourceValue);
                                zBuildingMapper.updateById(building);
                                if (StringUtils.isNotEmpty(vo.getUnitName())) {
                                    unit = zUnitMapper.getByName(vo.getUnitName(), building.getId());
                                    if (ObjectUtils.isEmpty(unit)) {
                                        unit = new ZUnit();
                                        //单元
                                        unit.setName(vo.getUnitName());
                                        unit.setAreaId(area.getId());
                                        unit.setBuildingId(building.getId());
                                        unit.setCreateBy(operName);
                                        unit.setCreateTime(new Date());
                                        unit.setSource(sourceValue);
                                        zUnitMapper.insert(unit);
                                        if (StringUtils.isNotEmpty(vo.getHouseName())) {
                                            //房屋
                                            house.setName(vo.getHouseName());
                                            house.setAreaId(area.getId());
                                            house.setBuildingId(building.getId());
                                            house.setUnitId(unit.getId());
                                            house.setCreateBy(operName);
                                            house.setCreateTime(new Date());
                                            house.setSource(sourceValue);
                                            house.setHouseUserName(vo.getHouseUserName());
                                            house.setIdCard(vo.getIdCard());
                                            house.setPhone(vo.getPhone());
                                            zHouseMapper.insert(house);
                                            successNum++;
                                        } else {
                                            throw new ServiceException("" + "第" + (n + 1) + "行格式错误,导入失败!");
                                        }
                                    } else {
                                        //单元
                                        unit.setAreaId(area.getId());
                                        unit.setBuildingId(building.getId());
                                        unit.setUpdateBy(operName);
                                        unit.setUpdateTime(new Date());
                                        unit.setSource(sourceValue);
                                        zUnitMapper.updateById(unit);
                                        if (StringUtils.isNotEmpty(vo.getHouseName())) {
                                            house = zHouseMapper.getByName(vo.getHouseName(), unit.getId());
                                            if (ObjectUtils.isEmpty(house)) {
                                                house = new ZHouse();
                                                //房屋
                                                house.setName(vo.getHouseName());
                                                house.setAreaId(area.getId());
                                                house.setBuildingId(building.getId());
                                                house.setUnitId(unit.getId());
                                                house.setCreateBy(operName);
                                                house.setCreateTime(new Date());
                                                house.setSource(sourceValue);
                                                house.setHouseUserName(vo.getHouseUserName());
                                                house.setIdCard(vo.getIdCard());
                                                house.setPhone(vo.getPhone());
                                                zHouseMapper.insert(house);
                                                successNum++;
                                            }else{
                                                //房屋
                                                house.setAreaId(area.getId());
                                                house.setBuildingId(building.getId());
                                                house.setUnitId(unit.getId());
                                                house.setUpdateBy(operName);
                                                house.setUpdateTime(new Date());
                                                house.setSource(sourceValue);
                                                house.setHouseUserName(vo.getHouseUserName());
                                                house.setIdCard(vo.getIdCard());
                                                house.setPhone(vo.getPhone());
                                                zHouseMapper.updateById(house);
                                            }
                                        } else {
                                            throw new ServiceException("" + "第" + (n + 1) + "行格式错误,导入失败!");
                                        }
                                    }
                                } else {
                                    throw new ServiceException("" + "第" + (n + 1) + "行格式错误,导入失败!");
                                }
                            }
                        } else {
                            throw new ServiceException("" + "第" + (n + 1) + "行格式错误,导入失败!");
                        }
                    }
                } else {
                    throw new ServiceException("" + "第" + (n + 1) + "行格式错误,导入失败!");
                }
            } catch (Exception e) {
                throw new ServiceException("" + "第" + (n + 1) + "行格式错误,导入失败!");
            }
            ret.put("bfb", String.format("%.2f", (Double.valueOf((n + 1)) / Double.valueOf(list.size())) * 100));
            ret.put("n", n);
            ret.put("is_success", true);
            ret.put("successMsg", "");
            ret.put("successNum", successNum);
            return ret;
        }
        successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条");
        ret.put("bfb", String.format("%.2f", (Double.valueOf((n + 1)) / Double.valueOf(list.size())) * 100));
        ret.put("n", n);
        ret.put("is_success", false);
        ret.put("successMsg", successMsg.toString());
        return ret;
    }

    /**
     * 小区下拉
     */
    @Override
    public List<ZAreaVo> getArea(String district) {
        return baseMapper.getArea(district);
    }

    /**
     * 查询小区管理
     */
    @Override
    public ZAreaVo queryById(String id) {
        return baseMapper.selectVoById(id);
    }

    /**
     * 查询小区管理列表
     */
    @Override
    public TableDataInfo<ZAreaVo> queryPageList(ZAreaBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<ZArea> lqw = buildQueryWrapper(bo);
        Page<ZAreaVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        for (ZAreaVo vo:result.getRecords()) {
            vo.setSource(zHouseMapper.getAreaSourceString("area_id",vo.getId()));
        }
        return TableDataInfo.build(result);
    }

    /**
     * 查询小区管理列表
     */
    @Override
    public List<ZAreaVo> queryList(ZAreaBo bo) {
        LambdaQueryWrapper<ZArea> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<ZArea> buildQueryWrapper(ZAreaBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<ZArea> lqw = Wrappers.lambdaQuery();
        lqw.orderByAsc(ZArea::getName);
        lqw.like(StringUtils.isNotBlank(bo.getName()), ZArea::getName, bo.getName());
        lqw.eq(StringUtils.isNotBlank(bo.getScale()), ZArea::getScale, bo.getScale());
        lqw.eq(bo.getReleaseIs() != null, ZArea::getReleaseIs, bo.getReleaseIs());
        lqw.eq(StringUtils.isNotBlank(bo.getReleaseBy()), ZArea::getReleaseBy, bo.getReleaseBy());
        lqw.eq(StringUtils.isNotBlank(bo.getDistrict()), ZArea::getDistrict, bo.getDistrict());
        lqw.eq(StringUtils.isNotBlank(bo.getCalculateDistrict()), ZArea::getCalculateDistrict, bo.getCalculateDistrict());
        lqw.eq(StringUtils.isNotBlank(bo.getBelongingPack()), ZArea::getBelongingPack, bo.getBelongingPack());
        lqw.like(StringUtils.isNotBlank(bo.getAdministrative()), ZArea::getAdministrative, bo.getAdministrative());
        return lqw;
    }

    /**
     * 新增小区管理
     */
    @Override
    public Boolean insertByBo(ZAreaBo bo) {
        ZArea add = BeanUtil.toBean(bo, ZArea.class);
        validEntityBeforeSave(add);
        add.setReleaseIs("001");
        add.setSource("0");
        if (!ObjectUtils.isEmpty(baseMapper.getByName(add.getName()))) {
            return false;
        }
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改小区管理
     */
    @Override
    public Boolean updateByBo(ZAreaBo bo) {
        ZArea update = BeanUtil.toBean(bo, ZArea.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(ZArea entity) {
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除小区管理
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<String> ids, Boolean isValid) {
        if (isValid) {

        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    /**
     * 导出所属包功能(名称查询)
     */
    @Override
    public String getDictNameOfAffiliatedPackage(ZAreaBo bo) {
        return baseMapper.getDictNameOfAffiliatedPackage(bo);
    }

    /**
     * 导出所属包功能(数据查询)
     */
    @Override
    public List<GExportsVo> getExport(ZAreaBo bo) {
        return baseMapper.getExport(bo);
    }

    /**
     * 图片下载
     */
    @Override
    public void upload(HttpServletRequest request, HttpServletResponse response, String id) {
        ZAreaVo vo =baseMapper.selectVoById(id);
        // 设置文件夹时间戳和路径位置
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String format = sdf.format(new Date());
        // 文件夹的路径，写入服务器的 /tmp 文件夹下
        String filePath = path + vo.getName();
        // 导出的zip路径
        String zipFilePath = path + "tmp_" + format + ".zip";
        // 导出的zip名字
        String zipName = "PHOTO_" + format + ".zip";

        // 调用工具类压缩文件夹
        FileOutputStream fileOutputStream = null;
        try {
            fileOutputStream = new FileOutputStream(new File(zipFilePath));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        FileUtil.toZip(filePath, fileOutputStream, true);

        // 调用工具类设置响应格式
        try {
            FileUtil.downLoadFile(request, response, zipName, zipFilePath);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException("导出失败~" + e);
        }
    }
}
