package pwc.taxtech.atms.web.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
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.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import pwc.taxtech.atms.common.DDUserInfoRes;
import pwc.taxtech.atms.common.HttpUtil;
import pwc.taxtech.atms.dto.ApiResultDto;
import pwc.taxtech.atms.dto.AtmsTokenDto;
import pwc.taxtech.atms.web.AtmsWebSettings;
import pwc.taxtech.atms.web.service.OrangeHeapService;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

@Controller
@RequestMapping("/")
public class IndexController {

    private static Logger logger = LoggerFactory.getLogger(IndexController.class);

    @Value("${api.url}")
    private String apiUrl;

    @Value("${get_user_info_url}")
    private String getUserInfoUrl;

    @Value("${app_id}")
    private String appId;

    @Value("${app_key}")
    private String appKey;

    @Autowired
    JwtUtil jwtUtil;

    @Autowired
    private AtmsWebSettings atmsWebSettings;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private OrangeHeapService orangeHeapService;
    /**
     *
     * @param atmsApiToken
     * @param ltpaToken
     * @param request
     * @param response
     * @return
     * @throws IOException
     * @throws ServletException
     */
    @RequestMapping(value = {"/", "/index", "/index.html"}, method = RequestMethod.GET)
    public String login(@CookieValue(value = "AtmsApiToken", required = false) String atmsApiToken,
                        @CookieValue(value = "LtpaToken", required = false) String ltpaToken,
                        HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        if (StringUtils.hasText(atmsApiToken)) {
            return "index";
        } else if (StringUtils.hasText(ltpaToken)) {
            String user = LtpaToken.validate(ltpaToken);
            if (StringUtils.isEmpty(user)) {
                return "redirect:Account/LogOn";
            } else {
                AtmsTokenDto token = new AtmsTokenDto();
                String accessToken = jwtUtil.generateToken(user, user, user);
                token.setAccess_token(accessToken);
                token.setToken_type("bearer");
                token.setExpires_in(86400000L);
                // api_host可以由atms-web端来赋值
                token.setApi_host(apiUrl);
                token.setVat_api_host(apiUrl);
                token.setTp_url(apiUrl);
                token.setVersion("1.0" + ".0.0");
                token.setUser_name(user);
                token.setLocal_name(user);
                token.setNeed_change_password(false);
                token.setIs_external_user(true);
                token.setUser_id(user);
                String cookieString = JSON.toJSONString(token);
                String cookieValue = URLEncoder.encode(cookieString, "UTF-8");
                Cookie cookie = new Cookie("AtmsApiToken", cookieValue);
                response.addCookie(cookie);
                return "redirect:index";
            }

        }
        return "redirect:Account/LogOn";
    }

    /**
     *
     * @param jumpto
     * @param code
     * @param response
     * @throws IOException
     * @throws ServletException
     */
    @RequestMapping(value = {"/sso/callback"})
    public void ddSSOCallback(@RequestParam(value = "jumpto") String jumpto,
                              @RequestParam(value = "code") String code,
                              HttpServletResponse response) throws IOException, ServletException {
        try {
            logger.info("jumpto=" + jumpto + "code=" + code);
            String ticketStr = getTicket(code);
            Cookie ddTicket = new Cookie("ddTicket", URLEncoder.encode(ticketStr, "UTF-8"));
            ddTicket.setPath("/");
            ddTicket.setMaxAge(18000);
            response.addCookie(ddTicket);
            response.sendRedirect(jumpto + "?code=" + code + "&ticketStr=" + ticketStr);
        } catch (Exception e) {
            logger.error("ddSSOCallback error", e);
        }
    }

    /**
     * 18/03/2019 20:46
     * 跨站cookie的问题,所以做了一次跳转
     * [code, ticketStr, request, response]
     *
     * @return
     * @author Gary J Li
     */
    @RequestMapping(value = {"/sso/accept"})
    public String accept(@RequestParam(value = "code") String code,
                         @RequestParam(value = "ticketStr") String ticketStr, HttpServletRequest request,
                         HttpServletResponse response) throws IOException, ServletException {
        StringBuffer url = request.getRequestURL();
        String tempContextUrl = url.delete(url.length() - request.getRequestURI().length(), url.length()).append("/").toString();
        try {
            Cookie codeCookie = new Cookie("ddCode", URLEncoder.encode(code, "UTF-8"));
            codeCookie.setPath("/");
            codeCookie.setMaxAge(18000);
            Cookie ddTicket = new Cookie("ddTicket", URLEncoder.encode(ticketStr, "UTF-8"));
            ddTicket.setPath("/");
            ddTicket.setMaxAge(18000);
            response.addCookie(codeCookie);
            response.addCookie(ddTicket);
        } catch (Exception e) {
            logger.error("ddSSOCallback error", e);
        }
        return "redirect:" + tempContextUrl;
    }

    @RequestMapping(value = {"/admin", "/admin.html"}, method = RequestMethod.GET)
    public String admin(@CookieValue(value = "AtmsApiToken", required = false) String atmsApiToken) {
        if (StringUtils.hasText( atmsApiToken)) {
            return "admin";
        }
        return "redirect:Account/LogOn";
    }

    public String getTicket(String code) {
        try {
            JSONObject object;
            String url = getUserInfoUrl + "check_code";
            String ddResp = HttpUtil.post(url, "code=" + code + "&app_key=" + appKey + "&app_id=" + appId, "application/x-www-form-urlencoded", "UTF-8", 10000, 10000);
            object = JSONObject.parseObject(ddResp);
            logger.info("get ddTicket by code , object=" + object);
            Map<String, Object> res = object.getInnerMap();
            int errno = (int) res.get("errno");
            if (errno != 0) {
                logger.warn(String.format("DD Ticket get Failed:[%s]", object.toJSONString()));
                return null;
            } else {

                Map<String, String> data = (Map) res.get("data");
                logger.info("check_code data=" + data);
                return data.get("ticket");
            }
        } catch (Exception e) {
            logger.error(String.format("通过code:[%s]获取Ticket失败", code));
        }
        return null;
    }

    /**
     *  sam
     * @param ticket
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = {"/sso/getUser"}, method = RequestMethod.GET)
    @ResponseBody
    public ApiResultDto accept(@RequestParam(value = "ticket") String ticket, HttpServletRequest request,
                         HttpServletResponse response) {
        DDUserInfoRes ddUserInfoRes = null;
        try {
            String responseDD = HttpUtil.post(getUserInfoUrl + "get_user_by_ticket", "ticket=" + ticket + "&app_id=" + appId, "application/x-www-form-urlencoded", "UTF-8", 10000, 10000);

            logger.info(String.format("DD-get_user_by_ticket返回:[%s]", responseDD));
            ddUserInfoRes = JSONObject.parseObject(responseDD, DDUserInfoRes.class);
        } catch (Exception e) {
            logger.info(String.format("调用DDSSO获取用户信息失败:[%s]", e.getMessage()), e);
        }
        return ApiResultDto.success(ddUserInfoRes);
    }


    @RequestMapping(value = {"/getCookie"}, method = RequestMethod.GET)
    @ResponseBody
    public String getCookie( HttpServletRequest request,
                         HttpServletResponse response) {

        orangeHeapService.getDDTicketByCookie(request);

        return null;
    }



}