package com.duiba.tuia.youtui.web.controller;

import cn.com.duiba.tuia.activity.center.api.code.BillCode;
import cn.com.duiba.tuia.activity.center.api.constant.AlipayOrderStatus;
import cn.com.duiba.tuia.activity.center.api.constant.ErrorCode;
import cn.com.duiba.tuia.activity.center.api.dto.AlipayOrderDto;
import cn.com.duiba.tuia.activity.center.api.dto.rsp.RechargeRsp;
import cn.com.duiba.wolf.utils.UrlUtils;
import com.duiba.tuia.youtui.web.bo.PrizeBO;
import com.duiba.tuia.youtui.web.log.InnerLogService;
import com.duiba.tuia.youtui.web.model.Result;
import com.duiba.tuia.youtui.web.model.req.BillReq;
import com.duiba.tuia.youtui.web.service.ActivityOrderService;
import com.duiba.tuia.youtui.web.tool.HttpRequestTool;
import com.duiba.tuia.youtui.web.tool.MD5;
import com.duiba.tuia.youtui.web.tool.RequestLocal;
import com.google.common.collect.Maps;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.io.IOException;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.util.Map;

@Controller
@RequestMapping("/bill")
@Api("话费API")
public class BillController extends BaseController {

    @Resource
    PrizeBO prizeBO;

    @Resource
    ActivityOrderService activityOrderService;

    public static final String COMPANY_ID = "1523";// test "3005"
    public static final String INTERFACE = "ti6iq5";// "6aoqwg"
    public static final String REQUEST_KEY = "nh5uea";//"8et542"
    public static final String ACCESS_KEY = "n8ukjm";//"p32qwg"
    public static final String URL = "http://wr.800617.com:6001/submit.aspx";//"http://test.800617.com:6001/submit.aspx"


    /**
     * 话费-填写信息
     * @param billReq
     * @return
     */
    @ResponseBody
    @RequestMapping("/submitBillPrize")
    @ApiOperation(value = "submitBillPrize", httpMethod = "GET", notes = "话费-提交手机号")
    public Result<Boolean> submitBillPrize(@ModelAttribute BillReq billReq) {
        try {
            return successResult(prizeBO.submitBillPrize(billReq,RequestLocal.get().getDeviceId()));
        } catch (Exception e) {
            logger.warn("submit error", e);
            return failResult(e);
        }
    }

    /**
     * 话费-领取结果
     *
     * @param orderId 订单
     * @return
     */
    @ResponseBody
    @RequestMapping("/billPrizeResult")
    @ApiOperation(value = "billPrizeResult", httpMethod = "GET", notes = "话费-领取结果")
    public Result<RechargeRsp> billResult(@Valid String orderId) {
        try {
            AlipayOrderDto order = activityOrderService.selectAlipayOrder(orderId);
            RechargeRsp rsp = new RechargeRsp();
            if (order != null) {
                if (AlipayOrderStatus.SUCCESS.getStatus().equals(order.getStatus())) {
                    rsp.setResult(ErrorCode.E0000000.getErrorCode());
                    rsp.setResultMsg(ErrorCode.E0000000.getDesc());
                } else if (AlipayOrderStatus.CONSUMER_ERROR.getStatus().equals(order.getStatus()) && BillCode.C1002.getCode().equals(order.getResultCode())) {
                    rsp.setResult(ErrorCode.E0200004.getErrorCode());
                    rsp.setResultMsg("手机号错误,请重新输入");
                    rsp.setSubCode(order.getResultCode());
                    rsp.setSubMsg(order.getResultMsg());
                } else if (ErrorCode.E0200006.getErrorCode().equals(order.getResultCode())) {
                    rsp.setResult(ErrorCode.E0200006.getErrorCode());
                    rsp.setResultMsg(ErrorCode.E0200006.getDesc());
                } else {
                    rsp.setResult(ErrorCode.E0200003.getErrorCode());
                    rsp.setResultMsg("充值中");
                    rsp.setSubCode(order.getResultCode());
                    rsp.setSubMsg(order.getResultMsg());
                }
            }
            return successResult(rsp);
        } catch (Exception e) {
            logger.warn("result error", e);
            return failResult(e);
        }
    }

    @RequestMapping("/test")
    @ResponseBody
    public String testInvoke(HttpServletRequest request) {
        try {
            String orderId = request.getParameter("orderId");
            String phone = request.getParameter("phone");
            String amount = request.getParameter("amount");
            return invoke(orderId, phone, amount);
        } catch (Exception e) {
            logger.warn("test invoke", e);
            return e.getMessage();
        }
    }

    @RequestMapping("/callback")
    @ResponseBody
    public String callback(HttpServletRequest request) {
        try {
            String companyId = request.getParameter("CompanyID");
            String mobile = request.getParameter("Mobile");
            String amount = request.getParameter("Amount");
            String orderId = request.getParameter("OrderID");
            String rs = request.getParameter("Result");
            String key = request.getParameter("Key");
            String msg = request.getParameter("Message");

            String check = MD5.md5(COMPANY_ID + mobile + amount + orderId + rs + ACCESS_KEY);
            if (!check.equals(key)) {
                return xml(BillCode.C1007.getCode());
            }

            if ("0".equals(rs)) {
                this.prizeBO.updatePrizeOrderSuccess(orderId);
            } else {
                this.prizeBO.updatePrizeOrderfailed(orderId, "", "回调返回错误,msg=" + msg);
            }

            String response = xml(BillCode.C0000.getCode());
            InnerLogService.httpLog(request.getRequestURL().toString(), "", response);

            return response;
        } catch (Exception e) {
            logger.warn("", e);
            return e.getMessage();
        }
    }

    private String xml(String content) {
        Document document = DocumentHelper.createDocument();
        document.setXMLEncoding("utf-8");
        Element ctuport = document.addElement("ctuport");
        Element result = ctuport.addElement("result");
        result.setText(content);
        return formatXml(document);
    }


    public String invoke(String orderId, String phone, String amount) {

        Map<String, String> params = Maps.newHashMap();

        try {
            String key = MD5.md5(new StringBuilder(COMPANY_ID).append(INTERFACE).append(phone).append(amount).append(orderId).append(REQUEST_KEY).toString());
            params.put("Key", key);
        } catch (NoSuchAlgorithmException e) {
            logger.warn("NoSuchAlgorithmException", e);
        } catch (UnsupportedEncodingException e) {
            logger.warn("UnsupportedEncodingException", e);
        }
        params.put("CompanyID", COMPANY_ID);
        params.put("InterfacePwd", INTERFACE);
        params.put("Amount", String.valueOf(amount));
        params.put("OrderID", orderId);
        params.put("Mobile", phone);

        String url = UrlUtils.appendParams(URL, params);

        return HttpRequestTool.requestByGet(url);
    }

    public String formatXml(Document document) {
        OutputFormat format = OutputFormat.createPrettyPrint();
        format.setEncoding("UTF-8");
        StringWriter sw = new StringWriter();
        XMLWriter xw = new XMLWriter(sw, format);
        xw.setEscapeText(false);
        try {
            xw.write(document);
            xw.flush();
            xw.close();
        } catch (IOException e) {
            logger.warn("xml format error", e);
        }
        return sw.toString();
    }
}
