package com.izouma.weixin.web;

import com.alipay.api.AlipayApiException;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.izouma.awesomeadmin.constant.AppConstant;
import com.izouma.awesomeadmin.dao.AlipayTempMapper;
import com.izouma.awesomeadmin.dto.Result;
import com.izouma.awesomeadmin.model.AlipayTemp;
import com.izouma.awesomeadmin.service.MemberCoinService;
import com.izouma.awesomeadmin.service.UserInfoService;
import com.izouma.awesomeadmin.service.UserOrderService;
import com.izouma.awesomeadmin.util.AlipayClientFactory;
import com.izouma.awesomeadmin.util.MbappUtil;
import com.izouma.awesomeadmin.util.PropertiesFileLoader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>支付宝相关控制。</p>
 *
 * @author 姓名 <br />
 * 更新履历 <br />
 * 日期 : 姓名: 更新内容<br />
 * @version 1.0
 */
@Controller
@RequestMapping("/aliapi")
//url：/模块/资源/{id}/细分
public class AlipayController {

    private static org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(AlipayController.class);

    @Autowired
    private UserOrderService userOrderService;

    @Autowired
    private MemberCoinService memberCoinService;

    @Autowired
    private UserInfoService userInfoService;


    @Autowired
    private AlipayTempMapper alipayTempMapper;


    @RequestMapping(value = "/appBuy", method = RequestMethod.GET)
    @ResponseBody
    public Result buy(@RequestParam(required = true, value = "orderId") String orderId,
                      @RequestParam(required = true, value = "coin") double coin, @RequestParam(required = true, value = "point") double point) {

        double cash = userOrderService.calculatedPrice(orderId, coin, point);
        if (cash > 0) {
            String totalAmount = cash + "";
            String outTradeNo = MbappUtil.create_out_trade_no();

            Map<String, String> maps = new HashMap<String, String>();
            maps.put("out_trade_no", outTradeNo);
            maps.put("total_amount", totalAmount);
            maps.put("subject", "一米世界-导航包");
            maps.put("seller_id", PropertiesFileLoader.getProperties("ALIPAY_SELLER"));
            // 下面两个 参数的 KEY 不要乱写 要和工具类里面对应
            //maps.put("ReturnUrl", MbappUtil.getDomain(request) + "index#/close");
            maps.put("NotifyUrl", PropertiesFileLoader.getProperties("base_domain") + "aliapi/async");
            try {
                String form = AlipayClientFactory.app_Pay(maps);
                if (!form.equals("err")) {

                    AlipayTemp alipayTemp = new AlipayTemp();

                    alipayTemp.setOrderId(orderId);
                    alipayTemp.setTotalAmount(BigDecimal.valueOf(cash));
                    alipayTemp.setTradeStatus(AppConstant.Aliapi.WAIT_BUYER_PAY);
                    alipayTemp.setOutTradeNo(outTradeNo);
                    alipayTemp.setCoin(BigDecimal.valueOf(coin));
                    alipayTemp.setPoint(BigDecimal.valueOf(point));
                    alipayTemp.setCash(BigDecimal.valueOf(cash));

                    alipayTempMapper.insertSelective(alipayTemp);

                    return new Result(true, new StringBuilder(form));

                }
            } catch (AlipayApiException e) {
                e.printStackTrace();
            }

        }
        return new Result(false, "错误");
    }


    /**
     * <p>充值舱豆。</p>
     *
     * @param request
     * @param response
     * @throws ServletException
     * @throws IOException
     */
    @RequestMapping(value = "/recharge", method = RequestMethod.GET)
    @ResponseBody
    public Result recharge(HttpServletRequest request, HttpServletResponse response) throws IOException {

        String money = request.getParameter("money");
        String userId = request.getParameter("userId");

        String outTradeNo = MbappUtil.create_out_trade_no();

        Map<String, String> maps = new HashMap<String, String>();
        maps.put("out_trade_no", outTradeNo);
        maps.put("total_amount", String.format("%.2f", Double.valueOf(money)));//PC支付需要两位小数
        maps.put("subject", "充值金币：" + money + " 个");
        maps.put("seller_id", PropertiesFileLoader.getProperties("ALIPAY_SELLER"));
        // 下面两个 参数的 KEY 不要乱写 要和工具类里面对应  
        //maps.put("ReturnUrl", MbappUtil.getDomain(request) + "index#/memberMoney");
        maps.put("NotifyUrl", PropertiesFileLoader.getProperties("base_domain") + "aliapi/rechargeAsync");
        try {
            String form = AlipayClientFactory.app_Pay(maps);
            if (!form.equals("err")) {

                AlipayTemp alipayTemp = new AlipayTemp();

                alipayTemp.setOrderId(userId);
                alipayTemp.setTotalAmount(BigDecimal.valueOf(Double.valueOf(money)));
                alipayTemp.setTradeStatus(AppConstant.Aliapi.WAIT_BUYER_PAY);
                alipayTemp.setOutTradeNo(outTradeNo);
                alipayTemp.setTypeFlag(AppConstant.Aliapi.RECHARGE);
                alipayTempMapper.insertSelective(alipayTemp);

                return new Result(true, new StringBuilder(form));
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }

        return new Result(false, "错误");
    }


    /**
     * 同步通知的页面的Controller
     *
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/return_url")
    public String Return_url(HttpServletRequest request, HttpServletResponse response) {

        return "pay/success.html";
    }


    /**
     * <p>充值回调接口。</p>
     *
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/recharge_return_url")
    public String recharge_return_url(HttpServletRequest request, HttpServletResponse response) {

        return "pay/recharge_success.html";
    }


    /**
     * 异步通知付款状态的Controller
     *
     * @param request
     * @param response
     * @return
     */
    @SuppressWarnings("rawtypes")
    @RequestMapping(value = "/async", method = RequestMethod.POST)
    public String async(HttpServletRequest request, HttpServletResponse response) {

        logger.info("支付宝支付订单回调");

        String tradeNo = request.getParameter("out_trade_no");
        String tradeStatus = request.getParameter("trade_status");
        if (tradeStatus.equals("TRADE_FINISHED") || tradeStatus.equals("TRADE_SUCCESS")) {
            //要写的逻辑。自己按自己的要求写
            System.out.println(">>>>>支付订单成功" + tradeNo);

            userOrderService.alipaySuccess(tradeNo, tradeStatus);
            return "pay/success.html";
        } else {//验证失败
            return "pay/fail.html";
        }

    }


    /**
     * <p>充值异步通知付款状态。</p>
     *
     * @param request
     * @param response
     * @return
     */
    @SuppressWarnings("rawtypes")
    @RequestMapping(value = "/rechargeAsync", method = RequestMethod.POST)
    public String rechargeAsync(HttpServletRequest request, HttpServletResponse response) {

        logger.info("支付宝支付充值回调");

        String tradeNo = request.getParameter("out_trade_no");
        String tradeStatus = request.getParameter("trade_status");
        if (tradeStatus.equals("TRADE_FINISHED") || tradeStatus.equals("TRADE_SUCCESS")) {
            //要写的逻辑。自己按自己的要求写
            System.out.println(">>>>>充值成功" + tradeNo);

            memberCoinService.alipaySuccess(tradeNo, tradeStatus);
            return "pay/cashPledge_success.html";
        } else {//验证失败  
            return "pay/cashPledge_fail.html";
        }

    }


    @RequestMapping(value = "/refund", method = RequestMethod.GET)
    @ResponseBody
    public void refund(@RequestParam(required = true, value = "outTradeNo") String outTradeNo,
                       @RequestParam(required = true, value = "refundAmount") double refundAmount) {

        String bizContent = "{" + "    \"out_trade_no\":\"" + outTradeNo + "\"," + "    \"refund_amount\":" + refundAmount + ","
                + "    \"refund_reason\":\"正常退款\"" + "  }";

        try {
            AlipayTradeRefundResponse response = AlipayClientFactory.refund(null, bizContent);
            if (response.isSuccess()) {
                System.out.println("调用成功");
            } else {
                System.out.println("调用失败");
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }

    }

    //产品名称:云通信短信API产品,开发者无需替换
    static final String product = "Dysmsapi";
    //产品域名,开发者无需替换
    static final String domain = "dysmsapi.aliyuncs.com";

    // TODO 此处需要替换成开发者自己的AK(在阿里云访问控制台寻找)
    static final String accessKeyId = PropertiesFileLoader.getDefaultProperties("aliossid", "");
    static final String accessKeySecret = PropertiesFileLoader.getDefaultProperties("aliosskey", "");

    @RequestMapping(value = "/sendCode", method = RequestMethod.GET)
    @ResponseBody
    public Result sendCode(@RequestParam("phone") String mobile, @RequestParam("templateCode") String templateCode, HttpServletRequest httpRequest) {
        try {
            //验证码
            String msgCode = MbappUtil.getRandomNum(6);

            //可自助调整超时时间
            System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
            System.setProperty("sun.net.client.defaultReadTimeout", "10000");

            //初始化acsClient,暂不支持region化
            IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);
            DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);
            IAcsClient acsClient = new DefaultAcsClient(profile);

            //组装请求对象-具体描述见控制台-文档部分内容
            SendSmsRequest request = new SendSmsRequest();
            //必填:待发送手机号
            request.setPhoneNumbers(mobile);
            //必填:短信签名-可在短信控制台中找到
            request.setSignName("图忆途");
            //必填:短信模板-可在短信控制台中找到
            request.setTemplateCode(templateCode);
            //可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
            request.setTemplateParam("{\"code\":\"" + msgCode + "\"}");

            //选填-上行短信扩展码(无特殊需求用户请忽略此字段)
            //request.setSmsUpExtendCode("90997");

            //可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
            //request.setOutId("yourOutId");

            //hint 此处可能会抛出异常，注意catch
            SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);

            if (sendSmsResponse.getCode() != null && sendSmsResponse.getCode().equals("OK")) {
                //请求成功
                httpRequest.getSession(true).setAttribute("aliMsgCode", msgCode);
                return new Result(true, "发送成功");
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        return new Result(false, "发送失败，请稍后重试");
    }

    @RequestMapping(value = "/verifyMsgCode", method = RequestMethod.GET)
    @ResponseBody
    public Result verifyMsgCode(HttpServletRequest request, @RequestParam("code") String code) {
        String rand = (String) request.getSession(true).getAttribute("aliMsgCode");
        if (code.toLowerCase().equals(rand)) {
            return new Result(true, null);
        } else {
            return new Result(false, "验证码错误");
        }
    }

}
