package cn.com.countrygarden.bi.main.controller.performance.indicators;

import cn.com.countrygarden.bi.main.controller.BaseController;
import cn.com.countrygarden.bi.main.core.Response;
import cn.com.countrygarden.bi.main.core.ResultCode;
import cn.com.countrygarden.bi.main.model.AccessToken;
import cn.com.countrygarden.bi.main.model.performance.dto.ElementDto;
import cn.com.countrygarden.bi.main.model.performance.dto.PerformanceShowDataDto;
import cn.com.countrygarden.bi.main.service.AccessTokenService;
import cn.com.countrygarden.bi.main.service.performance.DownloadService;
import cn.com.countrygarden.bi.main.service.performance.PerformanceElementService;
import cn.com.countrygarden.bi.main.service.performance.common.PerformanceService;
import cn.com.countrygarden.bi.main.service.performance.impl.indicators.*;
import cn.com.countrygarden.bi.main.service.performance.indicators.ComIndicatorService;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Lazy;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * 所有绩效的基类Controller
 *
 * @Author:Wyman
 * @Date:2018/10/24
 */
@Lazy
@RestController
@RequestMapping(value = "/performance")
public class BasePerformanceController<T> extends BaseController {

    private ComIndicatorService comIndicatorService;

    private ApplicationContext ac;

    @Autowired
    private PerformanceService performanceService;

    @Autowired
    private DownloadService downloadService;

    @Autowired
    private PerformanceElementService performanceElementService;

    @Autowired
    private BigCustSatisfyServiceImpl bigCustSatisfyServiceImpl;

    @Autowired
    private SmallCustSatisfyServiceImpl smallCustSatisfyServiceImpl;

    @Autowired
    private GetPropertyCostsServiceImpl getPropertyCostsServiceImpl;

    @Autowired
    private GetArrearsPropertyCostsServiceImpl getArrearsPropertyCostsServiceImpl;


    @Autowired
    private PretaxprofitServiceImpl pretaxprofitServiceImpl;


    @Autowired
    private CommunityServiceImpl communityServiceImpl;


    @Autowired
    private OutreachRevenueServiceImpl outreachRevenueServiceImpl;

    @Autowired
    private PermanagementareaServiceImpl permanagementareaServiceImpl;

    @Autowired
    private YuanaverageServiceImpl yuanaverageServiceImpl;

    @Autowired
    private CommunityITServiceImpl communityITServiceImpl;

    @Autowired
    private CardsServiceImpl    cardsServiceImpl;

    @Autowired
    private BurglaryServiceImpl    burglaryServiceImpl;

    @Autowired
    private    AccidentServiceImpl  accidentServiceImpl;
    @Autowired
    private  ParkingCostServiceImpl parkingCostServiceImpl;
    @Autowired
    private  NegativeEffectServiceImpl  negativeEffectServiceImpl;
    @Autowired
    private  OwnerSatisfyServiceImpl ownerSatisfyServiceImpl;
    @Autowired
    private CityPropertyCostServiceImpl cityPropertyCostServiceImpl;
    @Autowired
    private CityPropertyArrearServiceImpl cityPropertyArrearServiceImpl;
    @Autowired
    private PrincipalProfitServiceImpl principalProfitServiceImpl;
    @Autowired
    private CommunityTaxProfitServiceImpl communityTaxProfitServiceImpl;
    @Autowired
    private ProfitScaleServiceImpl profitScaleServiceImpl;
    @Autowired
    private FenghuanghuiServiceImpl fenghuanghuiServiceImpl;
    @Autowired
    private ShifanxianmuServiceImpl shifanxianmuServiceImpl;
    //存放指标id与其业务实现类的对应关系
    private final Map<Long,String> map = new HashMap<>();

    public BasePerformanceController(){
        //初始化Spring ApplicationContext上下文
        WebApplicationContext wc = ContextLoader.getCurrentWebApplicationContext();
        ServletContext sc = wc.getServletContext();
        ac = WebApplicationContextUtils.getWebApplicationContext(sc);

        //添加映射关系
        map.put(1001L,"bigCustSatisfyServiceImpl");
        map.put(1002L,"smallCustSatisfyServiceImpl");
        map.put(1003L,"getPropertyCostsServiceImpl");
        map.put(1004L,"getArrearsPropertyCostsServiceImpl");
        map.put(1005L,"pretaxprofitServiceImpl");
        map.put(1006L,"communityServiceImpl");
        map.put(1007L,"outreachRevenueServiceImpl");
        map.put(1008L,"permanagementareaServiceImpl");
        map.put(1009L,"yuanaverageServiceImpl");
        map.put(1010L,"communityITServiceImpl");
        map.put(1011L,"cardsServiceImpl");
        map.put(1012L,"burglaryServiceImpl");
        map.put(1013L,"accidentServiceImpl");
        map.put(1014L,"parkingCostServiceImpl");
        map.put(1015L,"negativeEffectServiceImpl");
        map.put(1016L,"ownerSatisfyServiceImpl");
        map.put(1017L,"cityPropertyCostServiceImpl");
        map.put(1018L,"cityPropertyArrearServiceImpl");
        map.put(1019L,"principalProfitServiceImpl");
        map.put(1020L,"communityTaxProfitServiceImpl");
        map.put(999L,"profitScaleServiceImpl");
        map.put(1021L,"fenghuanghuiServiceImpl");
        map.put(1022L,"shifanxianmuServiceImpl");
    }


    @GetMapping(value = "/dataupload/{elementId}/records")
    public Object getRocords(@PathVariable(value = "elementId") long elementId, @RequestParam(value = "typeNo") String typeNo,
                             @RequestParam(value = "pageCurr") int pageCurr, @RequestParam(value = "pageSize") int pageSize,
                             @RequestParam(value = "year") int year , @RequestParam(value = "quarter") String quarter) {

        initialComService(elementId);

        PerformanceShowDataDto exposer  = (PerformanceShowDataDto) comIndicatorService.showData(elementId,year,Integer.parseInt(quarter),pageCurr,pageSize,typeNo);

        return Response.response(exposer);
    }

    @PostMapping(value = "/dataupload/records")
    public Object save(@RequestBody List<Object> values) {

        LinkedHashMap map = (LinkedHashMap)values.get(0);
        long elementId = Long.parseLong(map.get("elementId").toString()) ;
        int year = Integer.parseInt(map.get("year").toString());
        int quarter = Integer.parseInt(map.get("quarter").toString());

        initialComService(elementId);

        PerformanceShowDataDto  exposer = (PerformanceShowDataDto)comIndicatorService.saveData(elementId,year,quarter,values);

        return Response.response(exposer);
    }

    @PostMapping(value = "/dataupload/{elementId}/power")
    public Object getPower(@PathVariable("elementId") long elementId, @RequestBody Map<String, Object> requestMap, HttpServletRequest request) {

        initialComService(elementId);

        Object result = comIndicatorService.selectAuthority(elementId,requestMap,request);

        return Response.response(result);
    }

    @PostMapping(value = "/dataupload/{elementId}/upload")
    public Object upload(@PathVariable(value = "elementId") long elementId,@RequestParam(value = "year") int year, @RequestParam(value = "quarter") int quarter,
                         @RequestParam(value = "name") String name,
                         @RequestParam(value = "uploadfile", required = true) MultipartFile multipartFile,
                         HttpServletRequest request,
                         HttpServletResponse response) {
        AccessToken token = this.getAccessToken();
        String operatorId = token.getUserCode();
        if (multipartFile == null) {
            return Response.responseFail("请选择需要上传的文件");
        } else if (name == null) {
            return Response.responseFail("请输入文件名");
        }
        CommonsMultipartFile commonsMultipartFile = (CommonsMultipartFile) multipartFile;
        if (commonsMultipartFile.isEmpty()) {
            return Response.responseFail("上传文件为空文件");
        }
        String fileName = commonsMultipartFile.getOriginalFilename();
        if (fileName.indexOf(".xlsx") <= 0 || fileName.indexOf(".xls") <= 0) {
            return Response.responseFail("上传文件应为excel文件格式为：xlsx 或 xls");
        }
        if(elementId == 1001L){
            bigCustSatisfyServiceImpl.uploadData(elementId,year,quarter,multipartFile,operatorId);
        }else if(elementId == 1002L){
            smallCustSatisfyServiceImpl.uploadData(elementId,year,quarter,multipartFile,operatorId);
        }else if(elementId == 1003L){
            getPropertyCostsServiceImpl.uploadData(elementId,year,quarter,multipartFile,operatorId);
        }else if(elementId == 1004L){
            getArrearsPropertyCostsServiceImpl.uploadData(elementId,year,quarter,multipartFile,operatorId);
        }else if(elementId == 1005L){
            pretaxprofitServiceImpl.uploadData(elementId,year,quarter,multipartFile,operatorId);
        }else if(elementId == 1006L){
            communityServiceImpl.uploadData(elementId,year,quarter,multipartFile,operatorId);
        }else if(elementId == 1007L){
            outreachRevenueServiceImpl.uploadData(elementId,year,quarter,multipartFile,operatorId);
        }else if(elementId == 1008L){
            permanagementareaServiceImpl.uploadData(elementId,year,quarter,multipartFile,operatorId);
        }else if(elementId == 1009L){
            yuanaverageServiceImpl.uploadData(elementId,year,quarter,multipartFile,operatorId);
        }else if(elementId == 1010L){
            communityITServiceImpl.uploadData(elementId,year,quarter,multipartFile,operatorId);
        }else if(elementId == 1011L){
            cardsServiceImpl.uploadData(elementId,year,quarter,multipartFile,operatorId);
        }else if(elementId == 1012L){
            burglaryServiceImpl.uploadData(elementId,year,quarter,multipartFile,operatorId);
        }else if(elementId == 1013L){
            accidentServiceImpl.uploadData(elementId,year,quarter,multipartFile,operatorId);
        }else if(elementId == 1014L){
            parkingCostServiceImpl.uploadData(elementId,year,quarter,multipartFile,operatorId);
        }else if(elementId == 1015L){
            negativeEffectServiceImpl.uploadData(elementId,year,quarter,multipartFile,operatorId);
        }else if(elementId == 1016L){
            ownerSatisfyServiceImpl.uploadData(elementId,year,quarter,multipartFile,operatorId);
        }else if(elementId == 1017L){
            cityPropertyCostServiceImpl.uploadData(elementId,year,quarter,multipartFile,operatorId);
        }else if(elementId == 1018L){
            cityPropertyArrearServiceImpl.uploadData(elementId,year,quarter,multipartFile,operatorId);
        }else if(elementId == 1019L){
            principalProfitServiceImpl.uploadData(elementId,year,quarter,multipartFile,operatorId);
        }else if(elementId == 1020L){
            communityTaxProfitServiceImpl.uploadData(elementId,year,quarter,multipartFile,operatorId);
        }else if(elementId == 999L){
            profitScaleServiceImpl.uploadData(elementId,year,quarter,multipartFile,operatorId);
        }else if(elementId == 1021L){
            fenghuanghuiServiceImpl.uploadData(elementId,year,quarter,multipartFile,operatorId);
        }else if(elementId == 1022L){
            shifanxianmuServiceImpl.uploadData(elementId,year,quarter,multipartFile,operatorId);
        }


        return Response.response("导入成功");
    }

    @GetMapping(value = "/{elementId}/templetExcel")
    public void getTempExcel(@PathVariable(value = "elementId")long elementId, @RequestParam(value = "typeNo") String typeNo, HttpServletResponse response){

        //获取文件名
        String elementName = performanceElementService.getElementNameById(elementId).getName();
        Workbook workbook;
        try {
            workbook = downloadService.createWorkbook(elementName,typeNo);
            //输出
            response.setHeader("Content-Disposition", "attachment; filename=" + new String(elementName.getBytes("gbk"), "ISO-8859-1") + ".xlsx");
            response.setHeader("Pragma", "No-cache");
            response.setHeader("Cache-Control", "no-cache");
            response.setDateHeader("Expire", 0);
            response.setContentType("application/vnd.ms-excel");
            OutputStream outputStream = response.getOutputStream();
            workbook.write(outputStream);
            //outputStream.flush();//将缓冲区中数据刷新
            outputStream.close();
        } catch (FileNotFoundException e) {
            Response.responseFail(e.getMessage());
        } catch (IOException e1){
            Response.responseFail("内部错误，请联系管理员!");
        }
    }

    @PostMapping(value = "/myPerformance/{typeNo}")
    public Object myPerformance(@PathVariable(value = "typeNo")String typeNo,int year,
                                @RequestParam(value = "organList", required = false) String[] organList){

        AccessToken token = this.getAccessToken();
        if (token == null || token.getUserCode() == null) {
            return Response.response(ResultCode.UNAUTHORIZED);
        }

        Object result = performanceService.myPerformance2(organList,year,token.getUserCode(),typeNo);
        return Response.response(result);
    }

    @PostMapping(value = "/myPerformance/areaInfo")
    public Object getAreaInfo(@RequestParam(value = "typeNo")String typeNo,
                              @RequestParam(value = "organList", required = false) String[] organList){
        AccessToken token = this.getAccessToken();
        if (token == null || token.getUserCode() == null) {
            return Response.response(ResultCode.UNAUTHORIZED);
        }

        Object result  = performanceService.getAreaInfo(organList,token.getUserCode(),typeNo);

        return Response.response(result);
    }

    /**
     * 我的考核(数据对比)
     */
    @PostMapping(value = "/myPerformance/quarterInfo")
    public Object myPerformance(@RequestParam(value = "typeNo")String typeNo,int year,
                                @RequestParam(value = "quarter") int quarter,
                                @RequestParam(value = "organList", required = false) String[] selectAreaList){
        AccessToken token = this.getAccessToken();
        if (token == null || token.getUserCode() == null) {
            return Response.response(ResultCode.UNAUTHORIZED);
        }

        Object result = performanceService.myPerformance(selectAreaList,year,quarter,token.getUserCode(),typeNo);

        return Response.response(result);
    }

    @PostMapping(value = "/myPerformance/areaSum")
    public Object getAreaSum(@RequestParam(value = "typeNo")String typeNo,int year,
                             @RequestParam(value = "organList", required = false) String[] selectAreaList){
        AccessToken token = this.getAccessToken();
        if (token == null || token.getUserCode() == null) {
            return Response.response(ResultCode.UNAUTHORIZED);
        }
        Object result = performanceService.getAreaSum(selectAreaList,year,token.getUserCode(),typeNo);
        return  Response.response(result);

    }

    @GetMapping(value = "/performanceAnalysis/{elementId}/aveScore")
    public  Object getAveScore(@RequestParam(value = "typeNo")String typeNo,
                               @PathVariable(value = "elementId")long elementId){
        AccessToken token = this.getAccessToken();
        if (token == null || token.getUserCode() == null) {
            return Response.response(ResultCode.UNAUTHORIZED);
        }
        Object result = performanceService.getElementAveScore(elementId);

        return  Response.response(result);

    }


    @GetMapping(value = "/performanceAnalysis/{elementId}/quarterScore")
    public Object performanceAnalysis(@RequestParam(value = "typeNo") String typeNo,
                                      @PathVariable(value = "elementId") long elementId,
                                      @RequestParam(value = "quarter") int quarter){
        AccessToken token = this.getAccessToken();
        if (token == null || token.getUserCode() == null) {
            return Response.response(ResultCode.UNAUTHORIZED);
        }
        Object result = performanceService.performanceAnalysis(elementId,typeNo,token.getUserCode(),quarter);

        return  Response.response(result);
    }

    /**
     * 根据类型获取所有指标
     * @param typeNo
     * @return
     */
    @GetMapping(value = "/elements")
    public Object getAllElements(@RequestParam(value = "typeNo")String typeNo){

        List<ElementDto>  list = performanceService.getAllElements(typeNo);

        return Response.response(list);
    }

    /**
     * 分类发布功能
     * @param
     */
    @PostMapping(value = "/release")
    public Object release(@RequestParam("typeNo")String typeNo){

        Object result = performanceService.releaseFun(typeNo);

        return  Response.response(result);
    }

    @GetMapping(value = "/publicStatus")
    public Object getPublicStatus(@RequestParam("typeNo")String typeNo){

        Object result = performanceService.publicStatus(typeNo);

        return  Response.response(result);
    }


    /**
     * 通过elementId初始化对应的serviceImpl
     * @param elementId
     */
    private void initialComService(long elementId){

        //1.获得elementId(done)
        //2.通过elementId找到对应的Service实现类(通过对应关系map)
        String beanName = map.get(elementId);
        //3.通过spring容器获取指标对应的实现类，注入到接口中
        comIndicatorService = (ComIndicatorService)ac.getBean(beanName);

    }


}
