package com.fjs.scenic.controller;

import java.io.IOException;
import java.text.DecimalFormat;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.fjs.scenic.cyt.utils.Md5Utils;
import com.fjs.scenic.entity.order.Orders;
import com.fjs.scenic.entity.user.User;
import com.fjs.scenic.service.ord.OrdersService;
import com.fjs.scenic.service.user.UserService;
import com.fjs.scenic.utils.AESUtil;
import com.fjs.scenic.utils.Cons;
import com.fjs.scenic.utils.ReturnResult;
import com.fjs.scenic.utils.WXPayUtil;

import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;

/**
 * 微信支付入口
 * @author LF
 * @date 2018-06-20 10:00
 * @version 1.0
 */
@RestController
@RequestMapping("/api/wechat/pay")
public class WeChatPayController {

    private static Logger log = LoggerFactory.getLogger(WeChatPayController.class);

    /**
     * 微信公众号、商户配置
     */
    @Value("${APPID}")
    private String appid;
    @Value("${MCH_ID}")
    private String mchId;
    @Value("${API_KEY}")
    private String apiKey;
    @Value("${CERT_FILE_NAME}")
    private String cert;
    @Value("${NOTIFY_URL}")
    private String notifyUrl;
    @Value("${FEFUND_NOTIFY}")
    private String fefundNotify;


    @PostConstruct
    public void init(){
        WXPayUtil.APPID = this.appid;
        WXPayUtil.MCH_ID = this.mchId;
        WXPayUtil.API_KEY = this.apiKey;
        AESUtil.secretKey = new SecretKeySpec(Md5Utils.MD5Encode(this.apiKey, "UTF-8").toLowerCase().getBytes(), "AES");
        WXPayUtil.CERT_FILE_NAME = this.cert;
        WXPayUtil.NOTIFY_URL = this.notifyUrl;
        WXPayUtil.FEFUND_NOTIFY = this.fefundNotify;
    }
    
    @Autowired
    private OrdersService ordersService;
    @Autowired
    private UserService userService;

    /** JSAPI-公众号支付(预下单) */
    @ApiOperation(value = "公众号支付(预下单)", notes = "公众号支付(预下单)")
    @GetMapping(value = "/order/{id}")
    public ReturnResult order(HttpServletRequest request, @ApiParam(required = true, name = "id", value = "订单ID") @PathVariable("id") Integer id)
            throws ServletException, IOException {
        Orders order = ordersService.selectByPrimaryKey(id);
        if(order == null){
            return new ReturnResult(200, "请检查订单号是否存在.", null);
        }
        if(!order.getStatus().equals(Cons.ORDER_STATUS.PAID)){
            return new ReturnResult(200, "支付失败:订单状态异常", null);
        }
        User user = userService.getUserById(order.getUserId());
        DecimalFormat decimalFormat = new DecimalFormat("#");
        double money = order.getTotelPrice();
        // 请求下单
        Map<String, String> map = WXPayUtil.order(order.getOrderNo(),
                decimalFormat.format(money), user.getOpenid(), getIpAddr(request));
        if (map != null) {
            return new ReturnResult(200, "预下单成功.", map);
        }
        return new ReturnResult(500, "预下单失败.", null);
    }

/*    @ApiOperation(value = "发起退款", notes = "发起退款",hidden=true)
    @GetMapping("/refund/test/{id}")
    public ReturnResult refund(@ApiParam(required = true, name = "id", value = "订单号") @PathVariable Integer id){
        Assert.notNull(id, "订单号不能为空.");
        // 订单合法性检查
        Orders order = ordersService.selectByPrimaryKey(id);
        if(order == null){
            return new ReturnResult(500, "请检查订单号是否存在.", null);
        }
        Byte status = (byte) Integer.parseInt(order.getStatus());
        if(!status.equals(Cons.ORDER_STATUS.REFUNDEDING)){
            log.error("订单状态异常");
            return new ReturnResult(500, "订单状态异常.", null);
        }
        DecimalFormat decimalFormat = new DecimalFormat("#");
        double money = order.getTotelPrice();
        boolean b = WXPayUtil.refund(order.getOrderNo(), decimalFormat.format(money), order.getOrderNo());
        //异步回掉修改订单
        if(b){
        	ordersService.updateByParam(" status=6 where id=" + id);
        }
        log.info("退款是否成功:{}", b);
        return null;
    }*/

/*    @ApiOperation(value = "查询订单的支付状态", notes = "查询订单的支付状态")
    @GetMapping("/query/{orderNo}")
    public ReturnResult query(@ApiParam(required = true, name = "orderNo", value = "订单号") @PathVariable String orderNo){
        Assert.notNull(orderNo, "订单号不能为空.");
        return new ReturnResult(Cons.RESULT_OK, "查询成功.", WXPayUtil.orderQuery(orderNo));
    }

    @ApiOperation(value = "查询订单的退款状态", notes = "查询订单的退款状态")
    @GetMapping("/refund/query/{refundNo}")
    public ReturnResult refundQuery(@ApiParam(required = true, name = "", value = "退款单单号") @PathVariable String refundNo){
        Assert.notNull(refundNo, "退款单单号不能为空.");
        return new ReturnResult(Cons.RESULT_OK, "查询成功.", WXPayUtil.refundQuery(refundNo));
    }*/
    
    
	/** 
     * 获取用户真实IP地址，不使用request.getRemoteAddr()的原因是有可能用户使用了代理软件方式避免真实IP地址, 
     * 可是，如果通过了多级反向代理的话，X-Forwarded-For的值并不止一个，而是一串IP值 
     *  
     * @return ip
     */
    private String getIpAddr(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for"); 
        System.out.println("x-forwarded-for ip: " + ip);
        if (ip != null && ip.length() != 0 && !"unknown".equalsIgnoreCase(ip)) {  
            // 多次反向代理后会有多个ip值，第一个ip才是真实ip
            if( ip.indexOf(",")!=-1 ){
                ip = ip.split(",")[0];
            }
        }  
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
            ip = request.getHeader("Proxy-Client-IP");  
            System.out.println("Proxy-Client-IP ip: " + ip);
        }  
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
            ip = request.getHeader("WL-Proxy-Client-IP");  
            System.out.println("WL-Proxy-Client-IP ip: " + ip);
        }  
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
            ip = request.getHeader("HTTP_CLIENT_IP");  
            System.out.println("HTTP_CLIENT_IP ip: " + ip);
        }  
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");  
            System.out.println("HTTP_X_FORWARDED_FOR ip: " + ip);
        }  
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
            ip = request.getHeader("X-Real-IP");  
            System.out.println("X-Real-IP ip: " + ip);
        }  
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
            ip = request.getRemoteAddr();  
            System.out.println("getRemoteAddr ip: " + ip);
        } 
        System.out.println("获取客户端ip: " + ip);
        return ip;  
    }

}

