package common.controller;

import com.google.common.collect.ImmutableList;
import common.model.*;
import common.service.ContractService;
import common.service.MenuService;
import common.task.ContractSendEmailThread;
import dic.OperateObjectTypeEnum;
import exception.TipException;
import org.apache.commons.io.IOUtils;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import security.annotation.CurrentAccount;
import util.NewUserLogThread;
import util.ResultModel;
import util.UserLogThread;
import util.ValidateUtil;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by mxq on 17/12/21.
 * 优先测试账号查询
 */
@Controller
@RequestMapping("{platform}/contract")
public class ContractController {

    @Autowired
    private ContractService service;


    @RequestMapping(value = "find", method = RequestMethod.GET)
    @ResponseBody
    public ResultModel findAll(@CurrentAccount User loginAccount, @PathVariable String platform,
                               @RequestParam String startDate, @RequestParam String endDate) {
        return ResultModel.OK(service.findAll(loginAccount,startDate, endDate, platform));
    }

    @RequestMapping(value = "export", method = RequestMethod.GET,produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
    @ResponseBody
    public ResponseEntity<byte[]> export(@CurrentAccount User loginAccount, @PathVariable String platform, @RequestParam String startDate
                                , @RequestParam String endDate, HttpServletRequest request, HttpServletResponse response) {
        List<Contract> contractList = service.findAll(loginAccount, startDate, endDate, platform);
        Map<String, String> map = new HashMap<>();
        map.put("wait", "未执行");
        map.put("executing", "执行中");
        map.put("end", "已结束");
        map.put("cancel", "作废");

        byte[] content = new byte[0];
        StringBuilder sb = new StringBuilder();
        sb.append("时间,合同编号,客户账号,签约方,销售,开始日期,结束日期,套餐类型,合同金额,折扣,收款金额,合同状态\r\n");
        if(ValidateUtil.isValid(contractList)){
            for (Contract c : contractList){
                sb.append(c.getDs()).append(",").append(c.getContractCode()).append(",").append(c.getEmail()).append(",").append(c.getCustomerBody()).append(",").append(c.getSaleName()).append(",")
                        .append(c.getStartDate()).append(",").append(c.getEndDate()).append(",").append(c.getPriceLevelName()).append(",").append(c.getMoney()).append(",").append(c.getRebate()).append(",").append(c.getPayMoney()).append(",")
                        .append(map.get(c.getStatus())).append("\r\n");
            }
        }
        InputStream in =  new  ByteArrayInputStream(sb.toString().getBytes());
        try {
            content  = IOUtils.toByteArray(in);
        } catch (IOException e) {
            e.printStackTrace();
        }
        HttpHeaders headers = new HttpHeaders();
        response.setHeader("filename", "contract.csv");
        response.setHeader("content-disposition", "attachment; filename=contract.csv");
        response.setHeader("Content-Type","text/csv");
        response.setContentType("APPLICATION/OCTET-STREAM");

        NewUserLogThread userlog = new NewUserLogThread(loginAccount.getEmail(), loginAccount.getName(), OperateObjectTypeEnum.CUSTOMER.getKey(), platform, "导出合同", startDate, endDate, request);
        userlog.start();
        //返回文件字符串
        return new ResponseEntity<byte[]>(content, headers, HttpStatus.CREATED);
    }

    @RequestMapping(value = "pay/export", method = RequestMethod.GET,produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
    @ResponseBody
    public ResponseEntity<byte[]> exportPay(@CurrentAccount User loginAccount, @RequestParam String startDate, @RequestParam String endDate,
                                             HttpServletRequest request, HttpServletResponse response, @PathVariable String platform) {
        List<ContractMoney> moneyList = service.findPayAll(startDate, endDate, platform);
        Map<String, String> map = new HashMap<>();
        map.put("pay", "收款");
        map.put("invoice", "收票");

        byte[] content = new byte[0];
        StringBuilder sb = new StringBuilder();
        sb.append("合同编号 ,客户账号 ,签约方 ,事项 ,金额 ,日期 ,修改人 \r\n");
        if(ValidateUtil.isValid(moneyList)){
            for (ContractMoney c : moneyList){
                sb.append(c.getContractCode()).append(",").append(c.getEmail()).append(",").append(c.getCompany()).append(",").append(map.get(c.getType())).append(",")
                        .append(c.getMoney()).append(",").append(c.getDs()).append(",").append(c.getCreateName()).append("\r\n");
            }
        }
        InputStream in =  new  ByteArrayInputStream(sb.toString().getBytes());
        try {
            content  = IOUtils.toByteArray(in);
        } catch (IOException e) {
            e.printStackTrace();
        }
        HttpHeaders headers = new HttpHeaders();
        response.setHeader("filename", "contract_pay.csv");
        response.setHeader("content-disposition", "attachment; filename=contract_pay.csv");
       // response.setHeader("Content-Type", "application/octet-stream;charset=UTF-8");
        response.setHeader("Content-Type","text/csv");
        response.setContentType("APPLICATION/OCTET-STREAM");

        NewUserLogThread userlog = new NewUserLogThread(loginAccount.getEmail(), loginAccount.getName(), OperateObjectTypeEnum.CUSTOMER.getKey(), platform, "导出收款开票", startDate, endDate, request);
        userlog.start();
        //返回文件字符串
        return new ResponseEntity<byte[]>(content, headers, HttpStatus.CREATED);
    }

    @RequestMapping(value = "findone", method = RequestMethod.GET)
    @ResponseBody
    public ResultModel findOne(@CurrentAccount User loginAccount, @RequestParam String code) {
        return ResultModel.OK(service.findOne(code));
    }

    @RequestMapping(value = "checkAccount", method = RequestMethod.GET)
    @ResponseBody
    public ResultModel checkAccount(@CurrentAccount User loginAccount, @RequestParam String email, @PathVariable String platform) {
        return ResultModel.OK(service.checkAccount(email, platform));
    }

    @RequestMapping(value = "checkTime", method = RequestMethod.GET)
    @ResponseBody
    public ResultModel checkTime(@RequestParam String type, @RequestParam String email,
                                 @RequestParam String platform, @RequestParam(required = false) String product) {
        return ResultModel.OK(service.checkTime(email, platform,type,product));
    }

    @RequestMapping(value = "find/body", method = RequestMethod.GET)
    @ResponseBody
    public ResultModel findBody(@CurrentAccount User loginAccount) {
        return ResultModel.OK(service.findBody());
    }

    @RequestMapping(value = "find/code", method = RequestMethod.GET)
    @ResponseBody
    public ResultModel findCode(@CurrentAccount User loginAccount, @RequestParam String code) {
        return ResultModel.OK(service.getContractCode(code));
    }

    @RequestMapping(value = "find/pricelevel", method = RequestMethod.GET)
    @ResponseBody
    public ResultModel findPricelevel(@CurrentAccount User loginAccount) {
        return ResultModel.OK(service.findSetmeal());
    }

    @RequestMapping(value = "find/increment", method = RequestMethod.GET)
    @ResponseBody
    public ResultModel findIncrement(@CurrentAccount User loginAccount) {
        return ResultModel.OK(service.findIncrement());
    }

    @RequestMapping(value = "find/rebat", method = RequestMethod.GET)
    @ResponseBody
    public ResultModel rebat(@CurrentAccount User loginAccount, @RequestParam String product,
                             @RequestParam Integer level, @RequestParam Long money) {
        return ResultModel.OK(service.getRebat(product, level, money));
    }

    @RequestMapping(value = "find/sale", method = RequestMethod.GET)
    @ResponseBody
    public ResultModel rebat(@CurrentAccount User loginAccount) {
        return ResultModel.OK(service.getSales());
    }


    @RequestMapping(value = "create", method = RequestMethod.POST)
    @ResponseBody
    public ResultModel create(@CurrentAccount User loginAccount, @RequestBody Contract contract, HttpServletRequest request) {
        Contract contract1 = service.create(loginAccount, contract);
        NewUserLogThread userlog = new NewUserLogThread(loginAccount.getEmail(), loginAccount.getName(), OperateObjectTypeEnum.CUSTOMER.getKey(), contract1.getContractCode(), "新建合同","",contract1.toString(), request);
        userlog.start();

        ContractSendEmailThread email = new ContractSendEmailThread(contract);
        email.start();
        return ResultModel.OK(contract1);
    }

    @RequestMapping(value = "update", method = RequestMethod.PUT)
    @ResponseBody
    public ResultModel update(@CurrentAccount User loginAccount, @RequestBody Contract contract, HttpServletRequest request) {
        Contract contract1 = service.update(loginAccount, contract);
        NewUserLogThread userlog = new NewUserLogThread(loginAccount.getEmail(), loginAccount.getName(), OperateObjectTypeEnum.CUSTOMER.getKey(), contract1.getContractCode(), "修改合同","",contract1.toString(), request);
        userlog.start();
        return ResultModel.OK(contract1);
    }

    @RequestMapping(value = "pay", method = RequestMethod.POST)
    @ResponseBody
    public ResultModel pay(@CurrentAccount User loginAccount, @RequestBody ContractMoney contract, HttpServletRequest request) {
        ContractMoney contract1 = service.pay(loginAccount, contract);
        NewUserLogThread userlog = new NewUserLogThread(loginAccount.getEmail(), loginAccount.getName(), OperateObjectTypeEnum.CUSTOMER.getKey(), contract1.getContractCode(), "收款开票","",contract1.toString(), request);
        userlog.start();
        return ResultModel.OK(contract1);
    }

    @RequestMapping(value = "change", method = RequestMethod.POST)
    @ResponseBody
    public ResultModel change(@CurrentAccount User loginAccount, @RequestBody ContractChange contract, HttpServletRequest request) {
        Contract contract1 = service.change(loginAccount, contract);
        NewUserLogThread userlog = new NewUserLogThread(loginAccount.getEmail(), loginAccount.getName(), OperateObjectTypeEnum.CUSTOMER.getKey(), contract1.getContractCode(), "修改套餐","",contract1.toString(), request);
        userlog.start();
        return ResultModel.OK(contract1);
    }

    @RequestMapping(value = "find/pay", method = RequestMethod.GET)
    @ResponseBody
    public ResultModel findPay(@CurrentAccount User loginAccount, @RequestParam String startDate,
                               @RequestParam String endDate, @RequestParam String code) {
        return ResultModel.OK(service.findPay(startDate, endDate, code));
    }

    @RequestMapping(value = "find/change", method = RequestMethod.GET)
    @ResponseBody
    public ResultModel findChange(@CurrentAccount User loginAccount, @RequestParam String startDate,
                                  @RequestParam String endDate, @RequestParam String code) {
        return ResultModel.OK(service.findChange(startDate, endDate, code));
    }

    @RequestMapping(value = "update/pay", method = RequestMethod.PUT)
    @ResponseBody
    public ResultModel updatePay(@CurrentAccount User loginAccount, @RequestBody ContractMoney contract, HttpServletRequest request) {
        Contract contract1 = service.updatePay(loginAccount, contract);
        NewUserLogThread userlog = new NewUserLogThread(loginAccount.getEmail(), loginAccount.getName(), OperateObjectTypeEnum.CUSTOMER.getKey(), contract1.getContractCode(), "修改收款开票","", service.updatePay(loginAccount, contract).toString(), request);
        userlog.start();
        return ResultModel.OK(contract1);
    }

    @RequestMapping(value = "find/payall", method = RequestMethod.GET)
    @ResponseBody
    public ResultModel findPayAll(@CurrentAccount User loginAccount, @RequestParam String startDate,
                               @RequestParam String endDate, @PathVariable String platform) {
        return ResultModel.OK(service.findPayAll(startDate, endDate, platform));
    }

    @RequestMapping(value = "build", method = RequestMethod.POST)
    @ResponseBody
    public ResultModel build(@RequestBody Contract contract, HttpServletRequest request) {

//        ContractSendEmailThread email = new ContractSendEmailThread(contract);
//        email.start();
        return ResultModel.OK(service.build(contract));
    }

}
