package com.testor.module.lease.controller;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.function.Consumer;

import com.testor.biz.sys.org.model.domain.SysOrg;
import com.testor.biz.sys.org.service.SysOrgService;
import com.testor.module.lease.model.dto.*;
import com.testor.module.safe.model.domain.TSafeHazardOrg;
import com.testor.module.safe.service.TSafeHazardOrgService;
import com.testor.module.sys.model.domian.NewSysOrg;
import com.testor.module.sys.service.NewSysOrgService;
import com.testor.module.sys.service.TOrgService;
import com.tongtech.tfw.backend.common.context.ContextUtils;
import com.tongtech.tfw.backend.common.models.sys.UserInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import lombok.extern.slf4j.Slf4j;
import com.tongtech.tfw.backend.core.helper.StringHelper;
import com.tongtech.tfw.backend.core.helper.ObjectHelper;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RestController;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tongtech.tfw.backend.common.biz.constants.BizConstants;
import com.tongtech.tfw.backend.common.biz.models.BaseResponse;
import com.tongtech.tfw.backend.common.biz.models.BaseResponseList;
import com.tongtech.tfw.backend.common.biz.models.BizGeneralResponse;
import com.tongtech.tfw.backend.common.models.supers.SuperController;
import com.tongtech.tfw.backend.core.helper.TypeHelper;

import com.testor.module.lease.model.domain.TLeaseBank;
import com.testor.module.lease.service.TLeaseBankService;

/**
 * 租赁库管理关系Controller
 *
 * @author testor-framework
 * @date 2022-07-20 10:09:54
 */
@RestController
@RequestMapping("/leaseBank")
@Api(value = "TLeaseBank", tags = "租赁库管理关系")
@Slf4j
public class TLeaseBankController extends SuperController {

    @Autowired
    private TLeaseBankService tLeaseBankService;

    @Autowired
    private NewSysOrgService newSysOrgService;

    @Autowired
    private SysOrgService sysOrgService;

    @Autowired
    private TOrgService tOrgService;

    @Autowired
    private TSafeHazardOrgService tSafeHazardOrgService;

    @ApiOperation(value = "获取首页地图 经纬度 ", notes = "Get TLeaseBank By Id")
    @GetMapping(value = "/getHomeMapCoordinate")
    public BaseResponse<List<SysOrg>> getHomeMapCoordinate(String orgId) {
        BaseResponse<List<SysOrg>> baseResponse = new BaseResponse<>();
        if (StringHelper.isEmpty(orgId)) {
            // 当前登录用户的组织机构id
            orgId = ContextUtils.getLoginUser().getOrgId();
        }
        // 获取当前的子机构
        List<SysOrg> orgList = sysOrgService.list(new QueryWrapper<SysOrg>()
                .eq(SysOrg.PARENT_ID, orgId)
                .eq(SysOrg.IS_DEPT, "0")
                .ne(SysOrg.STATUS, BizConstants.STATUS_DELETE)
        );
        baseResponse.setData(orgList);
        return baseResponse;
    }


    @ApiOperation(value = "获取首页地图统计 ", notes = "Get TLeaseBank By Id")
    @GetMapping(value = "/getHomeStatistics")
    public BaseResponse<List<HomeStatistics>> getHomeStatistics(String orgId) {
        BaseResponse<List<HomeStatistics>> baseResponse = new BaseResponse<>();

        if (StringHelper.isEmpty(orgId)) {
            // 当前登录用户的组织机构id
            orgId = ContextUtils.getLoginUser().getOrgId();
        }
        // 获取当前的子机构
        List<SysOrg> orgList = sysOrgService.list(new QueryWrapper<SysOrg>()
                .eq(SysOrg.PARENT_ID, orgId)
                .eq(SysOrg.IS_DEPT, "0")
                .ne(SysOrg.STATUS, BizConstants.STATUS_DELETE)
        );
        List<HomeStatistics> homeStatistics = new ArrayList<>();
        for (SysOrg sysOrg : orgList) {
            String orgId1 = sysOrg.getOrgId();
            HomeStatistics statistics = new HomeStatistics();
            // 获取危险源统计
            SourceOfDanger sourceOfDanger = getHomeRiskSource(orgId1).getData();
            // 获取隐患数量统计
            HiddenDanger hiddenDanger = getHiddenDanger(orgId1).getData();
            // 获取地图粮库数量
            GrainBlank grainBlank = getHomeGrain(orgId1).getData();
            //机构信息
            statistics.setLatitude(sysOrg.getLatitude());
            statistics.setLongitude(sysOrg.getLongitude());
            statistics.setOrgId(sysOrg.getOrgId());
            statistics.setOrgName(sysOrg.getOrgName());
            // 危险源
            statistics.setMajor(sourceOfDanger.getMajor());
            statistics.setRiskRourceNum(sourceOfDanger.getRiskRourceNum());
            statistics.setRiskPoint(sourceOfDanger.getRiskPoint());

            // 隐患
            statistics.setGeneral(hiddenDanger.getGeneral());
            statistics.setGreate(hiddenDanger.getGreate());
            statistics.setHiddenDangerCount(hiddenDanger.getHiddenDangerCount());

            // 粮库
            statistics.setFundsBankNum(grainBlank.getFundsBankNum());
            statistics.setBusinessDeptNum(grainBlank.getBusinessDeptNum());
            statistics.setTLeaseBankNUm(grainBlank.getTLeaseBankNUm());
            statistics.setCount(grainBlank.getCount());
            homeStatistics.add(statistics);
        }
        baseResponse.setData(homeStatistics);
        return baseResponse;
    }


    @ApiOperation(value = "首页地图危险源数量统计 ", notes = "Get TLeaseBank By Id")
    @GetMapping(value = "/getHomeRiskSource")
    public BaseResponse<SourceOfDanger> getHomeRiskSource(String orgId) {
        BaseResponse<SourceOfDanger> response = new BaseResponse<>();
        // 获取当前传入orgid 的本下级
        List<String> orgs = getSubordinate(orgId);
        // 获取危险源总数
        int RiskRourceNum = tLeaseBankService.getRiskRourceNum(orgs);
        // 获取重大危险源
        int major = tLeaseBankService.getMajor(orgs);
        // 获取风险点的数量
        int riskPoint = tLeaseBankService.getRiskPoint(orgs);
        SourceOfDanger sourceOfDanger = new SourceOfDanger();
        sourceOfDanger.setRiskRourceNum(RiskRourceNum);
        sourceOfDanger.setMajor(major);
        sourceOfDanger.setRiskPoint(riskPoint);
        response.setData(sourceOfDanger);
        return response;
    }

    @ApiOperation(value = "首页地图隐患数量统计 ", notes = "Get TLeaseBank By Id")
    @GetMapping(value = "/getHiddenDanger")
    public BaseResponse<HiddenDanger> getHiddenDanger(String orgId) {
        BaseResponse<HiddenDanger> baseResponse = new BaseResponse<>();
        HiddenDanger hiddenDanger = new HiddenDanger();
        // 获取当前年
        Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        // 获取当前传入orgid 的本下级
        List<String> orgs = getSubordinate(orgId);
        // 一般隐患
        List<TSafeHazardOrg> generals = tSafeHazardOrgService.list(new QueryWrapper<TSafeHazardOrg>()
                .in("org_id", orgs)
                .eq("\"level\"", "1")
                .like("create_date", year)
                .ne("status", BizConstants.STATUS_DELETE)
        );
        // 重大隐患
        List<TSafeHazardOrg> greats = tSafeHazardOrgService.list(new QueryWrapper<TSafeHazardOrg>()
                .in("org_id", orgs)
                .eq("\"level\"", "2")
                .like("create_date", year)
                .ne("status", BizConstants.STATUS_DELETE)
        );
        // 一般隐患数量
        int general = generals.size();
        // 重大隐患数量
        int great = greats.size();
        // 一般隐患数量
        hiddenDanger.setGeneral(general);
        // 重大隐患数量
        hiddenDanger.setGreate(great);
        int count = tSafeHazardOrgService.getHiddenDangerCount(orgId);
        // 隐患总数
        hiddenDanger.setHiddenDangerCount(count);
        baseResponse.setData(hiddenDanger);
        return baseResponse;
    }

    /**
     * 根据传入orgId 获取本级及下级
     *
     * @param orgId
     * @return
     */
    public List<String> getSubordinate(String orgId) {
        List<SysOrg> fundsBanks = sysOrgService.list(new QueryWrapper<SysOrg>()
                .eq(SysOrg.IS_DEPT, "0")
                .ne(SysOrg.STATUS, BizConstants.STATUS_DELETE)
                .and(new Consumer<QueryWrapper<SysOrg>>() {
                    @Override
                    public void accept(QueryWrapper<SysOrg> sysOrgQueryWrapper) {
                        sysOrgQueryWrapper.apply("FIND_IN_SET ('" + orgId + "',parent_ids)").or()
                                .eq(SysOrg.ORG_ID, orgId);
                    }
                })
        );
        // 存储权限范围内的组织结构id
        List<String> orgs = new ArrayList<>();
        fundsBanks.stream().forEach(item -> {
            orgs.add(item.getOrgId());
        });
        return orgs;
    }

    @ApiOperation(value = "首页地图粮库数量统计 ", notes = "Get TLeaseBank By Id")
    @GetMapping(value = "/getHomeGrain")
    public BaseResponse<GrainBlank> getHomeGrain(String orgId) {
        BaseResponse<GrainBlank> response = new BaseResponse<>();
        // 自有粮库
        Integer grainDepot = newSysOrgService.count(new QueryWrapper<NewSysOrg>()
                .eq(NewSysOrg.IS_DEPT, "0")
                .ne(NewSysOrg.STATUS, BizConstants.STATUS_DELETE)
                .and(q ->
                        q.apply("FIND_IN_SET ('" + orgId + "',parent_ids)")
                                .or()
                                .eq(SysOrg.ORG_ID, orgId)
                )
                .eq(NewSysOrg.NATURE, "4")
        );

        // 租赁库
        Integer rentalLibrary = newSysOrgService.count(new QueryWrapper<NewSysOrg>()
                .eq(NewSysOrg.IS_DEPT, "0")
                .ne(NewSysOrg.STATUS, BizConstants.STATUS_DELETE)
                .and(q ->
                        q.apply("FIND_IN_SET ('" + orgId + "',parent_ids)")
                                .or()
                                .eq(SysOrg.ORG_ID, orgId)
                )
                .eq(NewSysOrg.IS_RENT, "1")
        );

        // 自有粮库
        Integer businessDeptNum = newSysOrgService.count(new QueryWrapper<NewSysOrg>()
                .eq(NewSysOrg.IS_DEPT, "0")
                .ne(NewSysOrg.STATUS, BizConstants.STATUS_DELETE)
                .and(q ->
                        q.apply("FIND_IN_SET ('" + orgId + "',parent_ids)")
                                .or()
                                .eq(SysOrg.ORG_ID, orgId)
                )
                .eq(NewSysOrg.NATURE, "3")
        );

        GrainBlank grainBlank = new GrainBlank();
        grainBlank.setTLeaseBankNUm(rentalLibrary);
        grainBlank.setBusinessDeptNum(businessDeptNum);
        grainBlank.setFundsBankNum(grainDepot);
        grainBlank.setCount(grainDepot + rentalLibrary);
        response.setData(grainBlank);
        return response;
    }

    @ApiOperation(value = "获取当前机构下的租赁库 ", notes = "Get TLeaseBank By Id")
    @GetMapping(value = "/getOrgLease")
    public BaseResponse<List<TLeaseBank>> getOrgLease() {
        return tLeaseBankService.getOrgLease();
    }

    /* Generated Method*/
    @ApiOperation(value = "新增或者修改 租赁库管理关系", notes = "Add TLeaseBank")
    @PostMapping(value = "/add")
    public BaseResponse<TLeaseBank> addEntity(@RequestBody TLeaseBank addRequest) throws Exception {
        return tLeaseBankService.addEntity(addRequest);
    }

    @ApiOperation(value = "获取 租赁库管理关系 ", notes = "Get TLeaseBank By Id")
    @GetMapping(value = "/get")
    public BaseResponse<TLeaseBank> getById(String id) {
        return tLeaseBankService.getDetail(id);
    }

    @ApiOperation(value = "解除恢复租赁库 租赁库管理关系 ", notes = "Update TLeaseBank By Id")
    @PutMapping(value = "/update")
    public BaseResponse<BizGeneralResponse> updateEntity(@RequestBody TLeaseBank updateRequest) {
        return tLeaseBankService.updateEntity(updateRequest);
    }

    //    @ApiOperation(value = "删除 租赁库管理关系 ", notes = "delete TLeaseBank By Id")
//    @PutMapping(value = "/delete")
    public BaseResponse<BizGeneralResponse> deleteEntity(@RequestBody TLeaseBankDelParam deleteRequest) {
        BaseResponse<BizGeneralResponse> baseResponse = new BaseResponse<>();
        if (ObjectHelper.isNotEmpty(deleteRequest) && StringHelper.isNotEmpty(deleteRequest.getId())) {
            TLeaseBank data = new TLeaseBank();
            data.setId(deleteRequest.getId());
            data.setStatus(BizConstants.STATUS_DELETE);
            boolean result = tLeaseBankService.updateById(data);
            baseResponse.setData(
                    BizGeneralResponse.builder().result(TypeHelper.castToString(result)).build());
        }
        return baseResponse;
    }

    //    @ApiOperation(value = "批量删除租赁库管理关系", notes = "delete TLeaseBank by batch Id")
//    @PutMapping(value = "/batch_delete")
    public BaseResponse<BizGeneralResponse> deleteEntityBatch(
            @RequestBody TLeaseBankDelParam deleteRequest) {
        BaseResponse<BizGeneralResponse> baseResponse = new BaseResponse<>();
        if (ObjectHelper.isNotEmpty(deleteRequest) && (!deleteRequest.getIds().isEmpty())) {
            /* 批量删除 */
            List<TLeaseBank> tLeaseBankList = new ArrayList<>();
            for (String id : deleteRequest.getIds()) {
                TLeaseBank data = new TLeaseBank();
                data.setId(id);
                data.setStatus(BizConstants.STATUS_DELETE);
                tLeaseBankList.add(data);
            }
            boolean result = tLeaseBankService.updateBatchById(tLeaseBankList);
            baseResponse.setData(
                    BizGeneralResponse.builder().result(TypeHelper.castToString(result)).build());
        }
        return baseResponse;
    }

    @ApiOperation(value = "获取 租赁库管理关系 分页列表", notes = "List TLeaseBank with page")
    @PostMapping(value = "/list")
    public BaseResponse<BaseResponseList<TLeaseBank>> listEntity(@RequestBody TLeaseBankParam param) {
        BaseResponse<BaseResponseList<TLeaseBank>> baseResponse = new BaseResponse<>();
        Long page =
                StringHelper.isEmpty(param.getPage()) ? BizConstants.PAGE : Long.valueOf(param.getPage());
        Long limit =
                StringHelper.isEmpty(param.getLimit()) ? BizConstants.LIMIT : Long.valueOf(param.getLimit());
        Page<TLeaseBank> resultPage = new Page<>(page, limit);
        QueryWrapper<TLeaseBank> queryWrapper = this.createQuery(param);
        Page<TLeaseBank> resultList = tLeaseBankService.page(resultPage, queryWrapper);
        List<TLeaseBank> records = resultList.getRecords();
        if (records != null) {
            for (TLeaseBank record : records) {
                SysOrg byId = tOrgService.getRegionalCompany(record.getOrgId());
                if (byId != null) {
                    record.setRegionalCompany(byId.getOrgName());
                }
            }
        }
        BaseResponseList<TLeaseBank> baseResponseList = new BaseResponseList<>();
        baseResponseList.setData(records);
        baseResponseList.setTotal(resultList.getTotal());
        baseResponse.setData(baseResponseList);
        return baseResponse;
    }

    //    @ApiOperation(value = "获取 租赁库管理关系 列表", notes = "List TLeaseBank all")
//    @GetMapping(value = "/datas")
    public BaseResponse<BaseResponseList<TLeaseBank>> listAllEntity(TLeaseBankParam param) {
        BaseResponse<BaseResponseList<TLeaseBank>> baseResponse = new BaseResponse<>();
        // TODO 根据需求修改查询条件及查询参数
        QueryWrapper<TLeaseBank> queryWrapper = this.createQuery(param);
        List<TLeaseBank> resultList = tLeaseBankService.list(queryWrapper);
        BaseResponseList<TLeaseBank> baseResponseList = new BaseResponseList<>();
        baseResponseList.setData(resultList);
        baseResponseList.setTotal(resultList.size());
        baseResponse.setData(baseResponseList);
        return baseResponse;
    }

    /* Private Methods */

    /**
     * 列表查询条件及查询参数
     */
    private QueryWrapper<TLeaseBank> createQuery(TLeaseBankParam queryParam) {
        QueryWrapper<TLeaseBank> queryWrapper = new QueryWrapper<>();
        UserInfo loginUser = ContextUtils.getLoginUser();
        queryWrapper.orderByDesc(TLeaseBank.ORG_NAME);
        if (StringHelper.isNotEmpty(queryParam.getOrgName())) {
            queryWrapper.like(TLeaseBank.ORG_NAME, queryParam.getOrgName());
        }
        if (StringHelper.isNotEmpty(queryParam.getLeaseName())) {
            queryWrapper.like(TLeaseBank.LEASE_NAME, queryParam.getLeaseName());
        }
        if (StringHelper.isNotEmpty(queryParam.getOrgIds())) {
            queryWrapper.in(TLeaseBank.ORG_ID, queryParam.getOrgIds());
        } else {
            queryWrapper.eq(TLeaseBank.ORG_ID, loginUser.getOrgId());
        }
        if (StringHelper.isNotEmpty(queryParam.getStatus())) {
            queryWrapper.eq(TLeaseBank.STATUS, queryParam.getStatus());
        } else {
            queryWrapper.ne(TLeaseBank.STATUS, BizConstants.STATUS_DELETE);
        }
        if (StringHelper.isNotEmpty(queryParam.getOrderBy())) {
            if (StringHelper.isNotEmpty(queryParam.getOrderType())
                    && BizConstants.ASC.equals(queryParam.getOrderType())) {
                queryWrapper.orderByAsc(queryParam.getOrderBy());
            } else {
                queryWrapper.orderByDesc(queryParam.getOrderBy());
            }
        } else {
            queryWrapper.orderByDesc(TLeaseBank.UPDATE_DATE);
        }
        return queryWrapper;
    }
}
