package com.yeejoin.amos.boot.module.common.biz.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yeejoin.amos.boot.biz.common.constants.BizConstant;
import com.yeejoin.amos.boot.biz.common.controller.BaseController;
import com.yeejoin.amos.boot.biz.common.utils.EnumsUtils;
import com.yeejoin.amos.boot.biz.common.utils.QRCodeUtil;
import com.yeejoin.amos.boot.module.common.api.dto.WaterResourceCraneDto;
import com.yeejoin.amos.boot.module.common.api.dto.WaterResourceDto;
import com.yeejoin.amos.boot.module.common.api.dto.WaterResourceHydrantDto;
import com.yeejoin.amos.boot.module.common.api.dto.WaterResourceIotDto;
import com.yeejoin.amos.boot.module.common.api.dto.WaterResourceNaturalDto;
import com.yeejoin.amos.boot.module.common.api.dto.WaterResourcePoolDto;
import com.yeejoin.amos.boot.module.common.api.dto.WaterResourceTypeDto;
import com.yeejoin.amos.boot.module.common.api.entity.WaterResource;
import com.yeejoin.amos.boot.module.common.api.entity.WaterResourceCrane;
import com.yeejoin.amos.boot.module.common.api.entity.WaterResourceHydrant;
import com.yeejoin.amos.boot.module.common.api.entity.WaterResourceIot;
import com.yeejoin.amos.boot.module.common.api.entity.WaterResourceNatural;
import com.yeejoin.amos.boot.module.common.api.entity.WaterResourcePool;
import com.yeejoin.amos.boot.module.common.api.enums.WaterResourceTypeEnum;
import com.yeejoin.amos.boot.module.common.biz.service.impl.WaterResourceCraneServiceImpl;
import com.yeejoin.amos.boot.module.common.biz.service.impl.WaterResourceHydrantServiceImpl;
import com.yeejoin.amos.boot.module.common.biz.service.impl.WaterResourceIotServiceImpl;
import com.yeejoin.amos.boot.module.common.biz.service.impl.WaterResourceNaturalServiceImpl;
import com.yeejoin.amos.boot.module.common.biz.service.impl.WaterResourcePoolServiceImpl;
import com.yeejoin.amos.boot.module.common.biz.service.impl.WaterResourceServiceImpl;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.typroject.tyboot.core.foundation.enumeration.UserType;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;
import org.typroject.tyboot.core.restful.doc.TycloudOperation;
import org.typroject.tyboot.core.restful.utils.ResponseHelper;
import org.typroject.tyboot.core.restful.utils.ResponseModel;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;


/**
 * @author system_generator
 * @date 2021-06-29
 */
@RestController
@Api(tags = "消防水源Api")
@RequestMapping(value = "/water-resource")
public class WaterResourceController extends BaseController {

    @Autowired
    WaterResourceServiceImpl waterResourceServiceImpl;
    @Autowired
    WaterResourceCraneServiceImpl waterResourceCraneService;
    @Autowired
    WaterResourceHydrantServiceImpl waterResourceHydrantService;
    @Autowired
    WaterResourceNaturalServiceImpl waterResourceNaturalService;
    @Autowired
    WaterResourcePoolServiceImpl waterResourcePoolService;
    @Autowired
    WaterResourceIotServiceImpl waterResourceIotService;

    /**
     * 新增
     *
     * @return 返回结果
     */
    @TycloudOperation(ApiLevel = UserType.AGENCY)
    @PostMapping(value = "/save")
    @ApiOperation(httpMethod = "POST", value = "新增", notes = "新增")
    public ResponseModel<WaterResourceDto> save(@RequestBody WaterResourceDto model) {
        String resourceType = model.getResourceType();
        Optional<WaterResourceTypeEnum> resourceTypeEnum = EnumsUtils.getEnumObject(WaterResourceTypeEnum.class,
                e -> e.getCode().equals(resourceType));
        model.setResourceTypeName(resourceTypeEnum.get().getName());
        model.setRealityImg(JSONArray.toJSONString(model.getRealityImgList()));
        model.setOrientationImg(JSONArray.toJSONString(model.getOrientationImgList()));
        
        if(model.getAddress()!=null){
            JSONObject address = WaterResourceServiceImpl.getLongLatFromAddress(model.getAddress());
            model.setAddress(address.getString(BizConstant.ADDRESS));
            model.setLongitude(Double.valueOf(address.getString(BizConstant.LONGITUDE)));
            model.setLatitude(Double.valueOf(address.getString(BizConstant.LATITUDE)));
		 }
         
        if (!StringUtils.isEmpty(resourceType)) {
            switch (resourceType) {
                case "hydrant":
                    // 新增基础信息
                    model.setIsIot(true);
                    waterResourceServiceImpl.createWithModel(model);
                    // 新增属性信息
                    WaterResourceHydrantDto waterResourceHydrantDto = new WaterResourceHydrantDto();
                    BeanUtils.copyProperties(model, waterResourceHydrantDto);
                    waterResourceHydrantDto.setSequenceNbr(null);
                    waterResourceHydrantDto.setResourceId(model.getSequenceNbr());
                    waterResourceHydrantService.createWithModel(waterResourceHydrantDto);
                    break;
                case "crane":
                    // 新增基础信息
                    model.setIsIot(true);
                    waterResourceServiceImpl.createWithModel(model);
                    WaterResourceCraneDto waterResourceCraneDto = new WaterResourceCraneDto();
                    BeanUtils.copyProperties(model, waterResourceCraneDto);
                    waterResourceCraneDto.setSequenceNbr(null);
                    waterResourceCraneDto.setResourceId(model.getSequenceNbr());
                    waterResourceCraneService.createWithModel(waterResourceCraneDto);
                    break;
                case "natural":
                    // 新增基础信息
                    model.setIsIot(false);
                    waterResourceServiceImpl.createWithModel(model);
                    WaterResourceNaturalDto waterResourceNaturalDto = new WaterResourceNaturalDto();
                    BeanUtils.copyProperties(model, waterResourceNaturalDto);
                    waterResourceNaturalDto.setSequenceNbr(null);
                    waterResourceNaturalDto.setResourceId(model.getSequenceNbr());
                    waterResourceNaturalService.createWithModel(waterResourceNaturalDto);
                    break;
                case "pool":
                    // 新增基础信息
                    model.setIsIot(true);
                    waterResourceServiceImpl.createWithModel(model);
                    WaterResourcePoolDto waterResourcePoolDto = new WaterResourcePoolDto();
                    BeanUtils.copyProperties(model, waterResourcePoolDto);
                    waterResourcePoolDto.setSequenceNbr(null);
                    waterResourcePoolDto.setResourceId(model.getSequenceNbr());
                    waterResourcePoolService.createWithModel(waterResourcePoolDto);
                    break;
            }
            // 新增物联信息
            if (model.getIsIot()) {
                WaterResourceIotDto waterResourceIotDto = model.getWaterResourceIotDto();
                waterResourceIotDto.setResourceType(model.getResourceType());
                waterResourceIotDto.setResourceId(model.getSequenceNbr());
                waterResourceIotService.createWithModel(waterResourceIotDto);
            }
        } else {
            waterResourceServiceImpl.createWithModel(model);
        }
        return ResponseHelper.buildResponse(model);
    }

    /**
     * 根据sequenceNbr更新
     *
     * @param sequenceNbr 主键
     * @return 返回结果
     */
    @TycloudOperation(ApiLevel = UserType.AGENCY)
    @PutMapping(value = "/{sequenceNbr}")
    @ApiOperation(httpMethod = "PUT", value = "根据sequenceNbr更新", notes = "根据sequenceNbr更新")
    public ResponseModel<WaterResourceDto> updateBySequenceNbrWaterResource(@RequestBody WaterResourceDto model,
                                                                            @PathVariable(value = "sequenceNbr") Long sequenceNbr) {
        if (StringUtils.isNotEmpty(model.getAddress())) {
            JSONObject address = WaterResourceServiceImpl.getLongLatFromAddress(model.getAddress());
            model.setAddress(address.getString(BizConstant.ADDRESS));
            model.setLongitude(Double.valueOf(address.getString(BizConstant.LONGITUDE)));
            model.setLatitude(Double.valueOf(address.getString(BizConstant.LATITUDE)));
        }

        // 更新基本信息
        model.setSequenceNbr(sequenceNbr);
        model.setRealityImg(JSONArray.toJSONString(model.getRealityImgList()));
        model.setOrientationImg(JSONArray.toJSONString(model.getOrientationImgList()));
        WaterResourceDto waterResourceDto = waterResourceServiceImpl.updateWithModel(model);
        // 更新属性信息
        String resourceType = model.getResourceType();
        if (!StringUtils.isEmpty(resourceType)) {
            switch (resourceType) {
                case "hydrant":
                    WaterResourceHydrantDto waterResourceHydrantDto = new WaterResourceHydrantDto();
                    WaterResourceHydrant waterResourceHydrant =
                            waterResourceHydrantService.getOne(new QueryWrapper<WaterResourceHydrant>().eq(
                                    "resource_id",
                                    sequenceNbr));
                    BeanUtils.copyProperties(model, waterResourceHydrantDto);
                    waterResourceHydrantDto.setSequenceNbr(waterResourceHydrant.getSequenceNbr());
                    waterResourceHydrantService.updateWithModel(waterResourceHydrantDto);
                    break;
                case "crane":
                    WaterResourceCraneDto waterResourceCraneDto = new WaterResourceCraneDto();
                    WaterResourceCrane waterResourceCrane =
                            waterResourceCraneService.getOne(new QueryWrapper<WaterResourceCrane>().eq("resource_id",
                                    sequenceNbr));
                    BeanUtils.copyProperties(model, waterResourceCraneDto);
                    waterResourceCraneDto.setSequenceNbr(waterResourceCrane.getSequenceNbr());
                    waterResourceCraneService.updateWithModel(waterResourceCraneDto);
                    break;
                case "natural":
                    WaterResourceNaturalDto waterResourceNaturalDto = new WaterResourceNaturalDto();
                    WaterResourceNatural waterResourceNatural =
                            waterResourceNaturalService.getOne(new QueryWrapper<WaterResourceNatural>().eq(
                                    "resource_id",
                                    sequenceNbr));
                    BeanUtils.copyProperties(model, waterResourceNaturalDto);
                    waterResourceNaturalDto.setSequenceNbr(waterResourceNatural.getSequenceNbr());
                    waterResourceNaturalService.updateWithModel(waterResourceNaturalDto);
                    break;
                case "pool":
                    WaterResourcePoolDto waterResourcePoolDto = new WaterResourcePoolDto();
                    WaterResourcePool waterResourcePool =
                            waterResourcePoolService.getOne(new QueryWrapper<WaterResourcePool>().eq("resource_id",
                                    sequenceNbr));
                    BeanUtils.copyProperties(model, waterResourcePoolDto);
                    waterResourcePoolDto.setSequenceNbr(waterResourcePool.getSequenceNbr());
                    waterResourcePoolService.updateWithModel(waterResourcePoolDto);
                    break;
            }
        }
        // 更新物联信息
        if (model.getIsIot()) {
            WaterResourceIotDto waterResourceIotDto = model.getWaterResourceIotDto();
            waterResourceIotDto.setResourceId(sequenceNbr);
            waterResourceIotService.updateWithModel(waterResourceIotDto);
        }
        return ResponseHelper.buildResponse(waterResourceDto);
    }

    /**
     * 根据sequenceNbr删除
     *
     * @param sequenceNbr 主键
     * @return 返回结果
     */
    @TycloudOperation(ApiLevel = UserType.AGENCY)
    @DeleteMapping(value = "/{sequenceNbr}")
    @ApiOperation(httpMethod = "DELETE", value = "根据sequenceNbr删除", notes = "根据sequenceNbr删除")
    public ResponseModel<Boolean> deleteBySequenceNbr(@PathVariable(value = "sequenceNbr") Long sequenceNbr) {
        WaterResource waterResource = waterResourceServiceImpl.getById(sequenceNbr);
        WaterResourceDto waterResourceDto = new WaterResourceDto();
        BeanUtils.copyProperties(waterResource, waterResourceDto);
        waterResourceDto.setIsDelete(false);
        waterResourceServiceImpl.updateWithModel(waterResourceDto);
        return ResponseHelper.buildResponse(true);
    }

    /**
     * 批量删除
     *
     * @param sequenceNbrList 主键
     * @return 返回结果
     */
    @TycloudOperation(ApiLevel = UserType.AGENCY)
    @DeleteMapping(value = "/delete_batch")
    @ApiOperation(httpMethod = "DELETE", value = "批量删除", notes = "批量删除")
    public ResponseModel<Boolean> batchDeleteBySequenceNbrList(@RequestParam(value = "sequenceNbrList") List<Long> sequenceNbrList) {
        List<WaterResourceDto> waterResourceDtos = waterResourceServiceImpl.queryBatchSeq(sequenceNbrList);
        List<WaterResource> resourceList = waterResourceDtos.stream().map(item -> {
            WaterResource waterResource = new WaterResource();
            BeanUtils.copyProperties(item, waterResource);
            waterResource.setIsDelete(false);
            return waterResource;
        }).collect(Collectors.toList());
        boolean batchDelete = waterResourceServiceImpl.updateBatchById(resourceList);
        return ResponseHelper.buildResponse(batchDelete);
    }

    /**
     * 根据sequenceNbr查询
     *
     * @param sequenceNbr 主键
     * @return 返回结果
     */
    @TycloudOperation(ApiLevel = UserType.AGENCY)
    @GetMapping(value = "/{sequenceNbr}")
    @ApiOperation(httpMethod = "GET", value = "根据sequenceNbr查询单个", notes = "根据sequenceNbr查询单个")
    public ResponseModel<WaterResourceDto> selectOne(@PathVariable Long sequenceNbr) {
        // 查询基本信息
        WaterResourceDto waterResourceDto = waterResourceServiceImpl.queryBySeq(sequenceNbr);
        waterResourceDto.setRealityImgList(JSONArray.parseArray(waterResourceDto.getRealityImg(), Object.class));
        waterResourceDto.setOrientationImgList(JSONArray.parseArray(waterResourceDto.getOrientationImg()));
        Boolean isDelete = waterResourceDto.getIsDelete();
        // 查询属性信息
        String resourceType = waterResourceDto.getResourceType();
        if (!StringUtils.isEmpty(resourceType)) {
            switch (resourceType) {
                case "hydrant":
                    WaterResourceHydrant waterResourceHydrant =
                            waterResourceHydrantService.getOne(new QueryWrapper<WaterResourceHydrant>().eq(
                                    "resource_id",
                                    sequenceNbr));
                    BeanUtils.copyProperties(waterResourceHydrant, waterResourceDto);
                    break;
                case "crane":
                    WaterResourceCrane waterResourceCrane =
                            waterResourceCraneService.getOne(new QueryWrapper<WaterResourceCrane>().eq("resource_id",
                                    sequenceNbr));
                    BeanUtils.copyProperties(waterResourceCrane, waterResourceDto);
                    break;
                case "natural":
                    WaterResourceNatural waterResourceNatural =
                            waterResourceNaturalService.getOne(new QueryWrapper<WaterResourceNatural>().eq(
                                    "resource_id",
                                    sequenceNbr));
                    BeanUtils.copyProperties(waterResourceNatural, waterResourceDto);
                    break;
                case "pool":
                    WaterResourcePool waterResourcePool =
                            waterResourcePoolService.getOne(new QueryWrapper<WaterResourcePool>().eq("resource_id",
                                    sequenceNbr));
                    BeanUtils.copyProperties(waterResourcePool, waterResourceDto);
                    break;
            }
        }
        waterResourceDto.setSequenceNbr(sequenceNbr);
        waterResourceDto.setIsDelete(isDelete);
        // 查询物联参数
        if (waterResourceDto.getIsIot()) {
            WaterResourceIot waterResourceIot = waterResourceIotService.getOne(new QueryWrapper<WaterResourceIot>().eq(
                    "resource_id", sequenceNbr));
            WaterResourceIotDto waterResourceIotDto = new WaterResourceIotDto();
            if (!ValidationUtil.isEmpty(waterResourceIot)) {
                BeanUtils.copyProperties(waterResourceIot, waterResourceIotDto);
            }
            waterResourceDto.setWaterResourceIotDto(waterResourceIotDto);
        }
        return ResponseHelper.buildResponse(waterResourceDto);
    }

    /**
     * 列表分页查询
     *
     * @param current 当前页
     * @param size    每页大小
     * @return 返回结果
     */
    @TycloudOperation(ApiLevel = UserType.AGENCY)
    @GetMapping(value = "/page")
    @ApiOperation(httpMethod = "GET", value = "分页查询", notes = "分页查询")
    public ResponseModel<Page<WaterResourceDto>> queryForPage(@RequestParam(value = "current") int current,
                                                              @RequestParam(value = "size") int size, String name,
                                                              @RequestParam(value = "belongBuildingId", required = false) ArrayList<Long> belongBuildingId,
                                                              Long belongFightingSystemId, Long sequenceNbr,
                                                              String resourceType,
                                                              String classifyId) {
        Page<WaterResourceDto> page = new Page<>();
        page.setCurrent(current);
        page.setSize(size);
        return ResponseHelper.buildResponse(waterResourceServiceImpl.queryForWaterResourcePage(page, name, resourceType,
                belongBuildingId, belongFightingSystemId, sequenceNbr, classifyId));
    }

    /**
     * 列表全部数据查询
     *
     * @return 返回结果
     */
    @TycloudOperation(ApiLevel = UserType.AGENCY)
    @ApiOperation(httpMethod = "GET", value = "列表全部数据查询", notes = "列表全部数据查询")
    @GetMapping(value = "/list")
    public ResponseModel<List<WaterResourceDto>> selectForList() {
        return ResponseHelper.buildResponse(waterResourceServiceImpl.queryForWaterResourceList(true));
    }

    /**
     * 列表查询消防水资源
     *
     * @param name                   资源名称
     * @param sequenceNbr            资源编号
     * @param belongFightingSystemId 所属消防系统id
     * @param belongBuildingId       所在建筑id
     * @param belongBuilding         所在建筑
     * @param resourceType           资源类型（消火栓、消防水鹤、天然水源、消防水池）
     * @return
     */
    @TycloudOperation(ApiLevel = UserType.AGENCY)
    @ApiOperation(httpMethod = "GET", value = "根据条件查询列表", notes = "根据条件查询列表")
    @GetMapping(value = "/select_list")
    public ResponseModel<List<WaterResourceDto>> selectList(String name, Long sequenceNbr,
                                                            Long belongFightingSystemId, Long belongBuildingId,
                                                            String belongBuilding, String resourceType) {
        return ResponseHelper.buildResponse(waterResourceServiceImpl.queryWaterResourceList(true, name,
                sequenceNbr, belongFightingSystemId, belongBuildingId, belongBuilding, resourceType));
    }

    /**
     * 查询水资源类型列表
     *
     * @return
     */
    @TycloudOperation(ApiLevel = UserType.AGENCY)
    @ApiOperation(httpMethod = "GET", value = "查询水资源类型列表", notes = "查询水资源类型列表")
    @GetMapping(value = "/resource_type_list")
    public ResponseModel<List<WaterResourceTypeDto>> selectResourceTypeList() {
        return ResponseHelper.buildResponse(waterResourceServiceImpl.getWaterResourceTypeList(true));
    }

    /**
     * 生成二维码code
     *
     * @return string
     */
    @TycloudOperation(ApiLevel = UserType.AGENCY)
    @ApiOperation(value = "生成二维码code", notes = "生成二维码code")
    @GetMapping(value = "/qr/code")
    public ResponseModel<String> genQrCode() {
        return ResponseHelper.buildResponse(QRCodeUtil.generateQRCode());
    }
}
