package com.softwarebr.nunu.web.api;

import com.brframework.common.utils.ConvertObjectUtil;
import com.brframework.commondb.core.ControllerPageHandle;
import com.brframework.commonsecurity.core.SecurityContextHolder;
import com.brframework.commonweb.json.JSONResult;
import com.brframework.commonweb.json.Page;
import com.brframework.commonweb.json.PageParam;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.softwarebr.nunu.entity.go.Label;
import com.softwarebr.nunu.entity.go.Policy;
import com.softwarebr.nunu.entity.go.PolicyApply;
import com.softwarebr.nunu.entity.go.PolicyLabel;
import com.softwarebr.nunu.globals.SystemConst;
import com.softwarebr.nunu.json.api.center.ApiPolicyApplyQueryParam;
import com.softwarebr.nunu.json.api.center.ApiPolicyApplyResult;
import com.softwarebr.nunu.json.api.go.*;
import com.softwarebr.nunu.service.SearchService;
import com.softwarebr.nunu.service.go.LabelService;
import com.softwarebr.nunu.service.go.PolicyApplyService;
import com.softwarebr.nunu.service.go.PolicyLabelService;
import com.softwarebr.nunu.service.go.PolicyService;
import com.softwarebr.nunu.service.oper.AreaService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collector;
import java.util.stream.Collectors;

import static com.softwarebr.nunu.globals.SystemConst.CONSTANT_GROBAL_MYSQL_IN_QUERY_LIMIT;

/**
 * @author lilin
 * @date 2020-02-19 14:03:47
 */

@RestController
@Api(tags = "扶持政策")
@RequestMapping("/api/")
@Validated
public class ApiGoController {

    @Autowired
    private LabelService labelService;

    @Autowired
    private PolicyApplyService policyApplyService;

    @Autowired
    private PolicyService policyService;

    @Autowired
    private PolicyLabelService policyLabelService;

    @Autowired
    SearchService searchService;

    @Autowired
    private AreaService areaService;


    @ApiOperation(value = "我的政策申报列表")
    @GetMapping("access/v1/center/policy/apply/page")
    public JSONResult<Page<ApiPolicyApplyResult>> policyApplyPageV1(PageParam page, ApiPolicyApplyQueryParam param) {
        param.setMemberId(Long.valueOf(SecurityContextHolder.getSubject().getId()));
        Page<ApiPolicyApplyResult> applyPage = ControllerPageHandle.jpaPageConvertToPage(policyApplyService.page(page, param), page, ApiPolicyApplyResult.class);
        applyPage.getList().forEach(r -> {
            r.setPolicyApplyId(r.getId());
            Policy policy = policyService.accessObject(r.getPolicyId());
            r.setPolicyContent(policy.getContent());
            r.setTitle(policy.getTitle());
        });
        return JSONResult.ok(applyPage);
    }

    @ApiOperation(value = "相关政策(H5政策速递详情)")
    @GetMapping("v1/center/policy/relative/page/{policyId}")
    public JSONResult<Page<ApiPolicyResult>> relativePolicyPageV1(PageParam page, @PathVariable Long policyId) {
        List<PolicyLabel> policyLabel = policyLabelService.getPolicyLabel(policyId);
        Page<ApiPolicyResult> resultPage;
        if (policyLabel.size() > 0) {
            resultPage = ControllerPageHandle.jpaPageConvertToPage(policyService.relativePage(page, policyLabel), page, ApiPolicyResult.class);
        }else {
            resultPage = new Page<>(page.getPageIndex(), page.getPageSize(), 0);
        }
        if (resultPage.getTotal() > 0) {
            Map<Long, String> labelMap = labelService.getAll().stream().collect(Collectors.toMap(Label::getId, Label::getLabelName));
            for (ApiPolicyResult apiPolicyResult : resultPage.getList()) {
                apiPolicyResult.setPolicyId(apiPolicyResult.getId());
                apiPolicyResult.setLabelInfoList(policyLabelHandle(apiPolicyResult.getId(), labelMap));
                apiPolicyResult.setCity(apiPolicyResult.getCityId() != null ? areaService.accessObject(apiPolicyResult.getCityId()).getCityName() : null);
                apiPolicyResult.setArea(apiPolicyResult.getAreaId() != null ? areaService.accessObject(apiPolicyResult.getAreaId()).getCityName() : null);
                apiPolicyResult.setProvince(apiPolicyResult.getProvinceId() != null ? areaService.accessObject(apiPolicyResult.getProvinceId()).getCityName() : null);
            }

        }
        return JSONResult.ok(resultPage);
    }

    @ApiOperation(value = "推荐政策列表(pc端及H5端的政策速递)", notes = "仅显示的政策")
    @PostMapping("v1/center/policy/recommend/page")
    public JSONResult<Page<ApiPolicyResult>> recommendPolicyPageV1(@RequestBody ApiPolicyQueryParam param) {
        PageParam pageParam = new PageParam();
        pageParam.setPageIndex(param.getPageIndex());
        pageParam.setPageSize(param.getPageSize());
        return JSONResult.ok(policyPageHandle(pageParam, param, false, false));
    }

    @ApiOperation(value = "可申报政策列表(pc端及H5端的政策申报)", notes = "可申报的政策")
    @PostMapping("v1/center/policy/apply/page")
    public JSONResult<Page<ApiPolicyResult>> appliedPolicyPageV1(@RequestBody ApiPolicyQueryParam param) {
        PageParam pageParam = new PageParam();
        pageParam.setPageIndex(param.getPageIndex());
        pageParam.setPageSize(param.getPageSize());
        return JSONResult.ok(policyPageHandle(pageParam, param, true, false));
    }

    @ApiOperation(value = "首页政策列表(pc端及H5端)")
    @GetMapping("v1/center/policy/index/page")
    public JSONResult<Page<ApiPolicyResult>> indexPolicyPageV1(PageParam page) {

        return JSONResult.ok(policyPageHandle(page, new ApiPolicyQueryParam(), true, true));
    }

    private Page<ApiPolicyResult> policyPageHandle(PageParam page, ApiPolicyQueryParam param, boolean applyStatus, boolean index) {
        PolicyPageQueryParam pageQueryParam = policyQueryParamHandle(param, applyStatus, index);

        Page<ApiPolicyResult> apiPolicyResultPage
                = ControllerPageHandle.jpaPageConvertToPage(policyService.page(page, pageQueryParam), page, ApiPolicyResult.class);
        if (apiPolicyResultPage.getList().size() > 0) {
            Map<Long, String> labelMap = labelService.getAll().stream().collect(Collectors.toMap(Label::getId, Label::getLabelName));
            apiPolicyResultPage.getList().forEach(policy -> {
                policy.setPolicyId(policy.getId());
                policy.setLabelInfoList(policyLabelHandle(policy.getId(), labelMap));
                policy.setApplyTotal(policyApplyService.countApplyTotal(policy.getId()).intValue());
                policy.setCity(policy.getCityId() != null ? areaService.accessObject(policy.getCityId()).getCityName() : null);
                policy.setArea(policy.getAreaId() != null ? areaService.accessObject(policy.getAreaId()).getCityName() : null);
                policy.setProvince(policy.getProvinceId() != null ? areaService.accessObject(policy.getProvinceId()).getCityName() : null);

            });
        }
        return apiPolicyResultPage;
    }

    private List<LabelInfo> policyLabelHandle(Long policyId, Map<Long, String> labelMap) {
        List<LabelInfo> labelInfoList = Lists.newArrayList();
        LabelInfo labelInfo;
        List<PolicyLabel> policyLabelList = policyLabelService.getPolicyLabel(policyId);
        for (PolicyLabel policyLabel : policyLabelList) {
            if (policyLabel.getParentId() != null) {
                String firstLabelName = labelMap.get(policyLabel.getParentId());
                if (firstLabelName != null) {
                    labelInfo = new LabelInfo();
                    labelInfo.setFirstLabelName(firstLabelName);
                    if (policyLabel.getChildId() != null) {
                        String secondLabelName = labelMap.get(policyLabel.getChildId());
                        labelInfo.setSecondLabelName(secondLabelName);
                    }
                    labelInfoList.add(labelInfo);
                }
            }
        }

        return labelInfoList;
    }


    /**
     * 政策查询条件处理
     *
     * @param param
     * @param applyStatus true 可申报的政策 false 仅显示的政策
     * @return
     */
    private PolicyPageQueryParam policyQueryParamHandle(ApiPolicyQueryParam param, boolean applyStatus, boolean index) {
        PolicyPageQueryParam pageQueryParam = new PolicyPageQueryParam();
        pageQueryParam.setId(getPolicyIds(param.getLabelParamList()));
        if (param.getProvince() != null) {
            pageQueryParam.setProvinceId(param.getProvince());
        }
        if (param.getCity() != null) {
            pageQueryParam.setCityId(param.getCity());
        }
        if (param.getArea() != null) {
            pageQueryParam.setAreaId(param.getArea());
        }
        if (index) {
            pageQueryParam.setIndexType(SystemConst.INDEX_TYPE_YES);
        } else {
            if (applyStatus) {
                pageQueryParam.setApplyStatus(Policy.APPLY_STATUS_YES);
            } else {
                pageQueryParam.setApplyStatus(Policy.APPLY_STATUS_DISPLAY);
            }
        }
        if (StringUtils.isNotEmpty(param.getTitle())) {
            pageQueryParam.setTitle(param.getTitle());
            searchService.increasingScore(param.getTitle());
        }
        pageQueryParam.setMarker(SystemConst.MARKER_STATUS_NO);
        pageQueryParam.setVerify(SystemConst.VERIFY_ADOPT);
        pageQueryParam.setStatus(SystemConst.STATUS_UPPER_SHELF);
        return pageQueryParam;
    }

    private Long[] getPolicyIds(List<LabelParam> labelParamList) {
        if (labelParamList != null && labelParamList.size() > 0) {
            List<Long> secondLabelId = labelParamList.stream().map(LabelParam::getSecondLabelId).collect(Collectors.toList());
            List<PolicyLabel> labels = policyLabelService.getByLabels(secondLabelId);
            return labels.stream().map(PolicyLabel::getPolicyId).collect(Collectors.toList()).toArray(new Long[labels.size()]);
        }
        return null;
    }


    @ApiOperation(value = "政策申报", notes = "注意传政策id")
    @PutMapping("access/v1/go/policy/apply/{policyId}")
    public JSONResult<PolicyApplyResult> userApplyPolicyV1(@PathVariable Long policyId, @Valid @RequestBody ApplyPolicyParam param) {
        PolicyApply policyApply = policyApplyService.saveApply(policyId, Long.valueOf(SecurityContextHolder.getSubject().getId()), param.getContent()
                , param.getContact(), param.getContactPhone(), param.getEmail());
        PolicyApplyResult applyResult = policyApplyHandle(policyApply);
        return JSONResult.ok(applyResult);
    }

    @ApiOperation(value = "申报结果", notes = "申报结果")
    @GetMapping("access/v1/go/policy/apply/result/{policyApplyId}")
    public JSONResult<PolicyApplyResult> applyPolicyResultV1(@ApiParam("政策申报id") @PathVariable Long policyApplyId) {
        PolicyApply policyApply = policyApplyService.accessObject(policyApplyId);
        PolicyApplyResult policyApplyResult = ControllerPageHandle.convertTo(policyApply, PolicyApplyResult.class);
        policyApplyResult.setApplyContent(policyApply.getContent());
        policyApplyResult.setPolicyApplyId(policyApplyResult.getId());
        policyApplyResult = ConvertObjectUtil.convertJavaBean(policyApplyResult, policyResultHandle(policyApply.getPolicyId()), true);
        return JSONResult.ok(policyApplyResult);
    }

    @ApiOperation(value = "政策详情", notes = "注意传政策id")
    @GetMapping("access/v1/go/policy/apply/{policyId}")
    public JSONResult<ApiPolicyResult> applyPolicyDetailV1(@PathVariable Long policyId) {
        return JSONResult.ok(policyResultHandle(policyId));
    }

    private ApiPolicyResult policyResultHandle(Long policyId){
        ApiPolicyResult policyResult = ControllerPageHandle.convertTo(policyService.accessObject(policyId), ApiPolicyResult.class);
        Map<Long, String> labelMap = labelService.getAll().stream().collect(Collectors.toMap(Label::getId, Label::getLabelName));
        policyResult.setLabelInfoList(policyLabelHandle(policyResult.getId(), labelMap));
        policyResult.setCity(policyResult.getCityId() != null ? areaService.accessObject(policyResult.getCityId()).getCityName() : null);
        policyResult.setArea(policyResult.getAreaId() != null ? areaService.accessObject(policyResult.getAreaId()).getCityName() : null);
        policyResult.setProvince(policyResult.getProvinceId() != null ? areaService.accessObject(policyResult.getProvinceId()).getCityName() : null);
        return policyResult;
    }

    private PolicyApplyResult policyApplyHandle(PolicyApply policyApply) {
        PolicyApplyResult applyResult = ControllerPageHandle.convertTo(policyApply, PolicyApplyResult.class);
        applyResult.setPolicyApplyId(applyResult.getId());
        return applyResult;
    }

    @ApiOperation(value = "政策查询参数")
    @GetMapping("v1/go/policy/param/list")
    public JSONResult<List<LabelResult>> getLabelQueryParamV1() {
        List<LabelResult> resultList = Lists.newArrayList();
        List<Label> labelList = labelService.getAll();
        Map<Long, List<Label>> labelMap = labelList.stream().collect(Collectors.groupingBy(Label::getParentId));
        List<Label> parentLabelList = labelMap.get(0L);
        //没时间去想递归了
        LabelResult param;
        for (Label label : parentLabelList) {
            param = new LabelResult();
            param.setLabelId(label.getId());
            param.setLabelName(label.getLabelName());
            List<Label> childLabels = labelMap.get(label.getId());
            if (childLabels != null) {
                List<LabelResult> childLabelResultList = Lists.newArrayList();
                for (Label childLabel : childLabels) {
                    LabelResult childLabelResult = new LabelResult();
                    childLabelResult.setLabelId(childLabel.getId());
                    childLabelResult.setLabelName(childLabel.getLabelName());
                    childLabelResultList.add(childLabelResult);
                }
                param.setChildLabelList(childLabelResultList);
            }
            resultList.add(param);
        }

        return JSONResult.ok(resultList);
    }

    @ApiOperation(value = "热门搜索关键词")
    @GetMapping("v1/go/policy/search/keyword")
    public JSONResult<SearchKeyWord> getHotKeyWordV1() {
        List<String> hotKeyWord = searchService.getHotKeyWord(3);
        SearchKeyWord keyWord = new SearchKeyWord();
        keyWord.setKeyWordList(hotKeyWord);
        return JSONResult.ok(keyWord);
    }

}