package pwc.taxtech.atms.web.service;

import com.alibaba.fastjson.JSONObject;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import pwc.taxtech.atms.common.DDUserInfoRes;
import pwc.taxtech.atms.common.HttpUtil;
import pwc.taxtech.atms.web.OrangeHeapConfig;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

@Service
public class OrangeHeapService {

    @Resource
    private OrangeHeapConfig systemConfig;

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


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

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

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


    public Optional<String> getTicket(String username) {
        CloseableHttpClient httpClient = null;
        try {
            String ticketUrl = String.format(systemConfig.getTableauGetTicket(), username);
            logger.info("进去获取tableau的url" + ticketUrl);
            httpClient = HttpClients.createDefault();
            HttpPost httpPost = new HttpPost(ticketUrl);
            HttpResponse httpResponse = httpClient.execute(httpPost);
            String response = IOUtils.toString(httpResponse.getEntity().getContent(), "UTF-8");
            logger.info("获取tableau的结果" + response);
            return StringUtils.equals(response, "-1") ? Optional.empty() : Optional.of(response);
        } catch (Exception e) {
            logger.error("getTicket error.", e);
        } finally {
            if (null != httpClient) {
                try {
                    httpClient.close();
                } catch (IOException e) {
                    logger.error("close httpClient error.", e);
                }
            }
        }
        return Optional.empty();
    }

    //税种未返还税金
//    public Optional<String> getTableauTaxCategoryUnreturnedTax() {
//        Optional<String> optional = Optional.of("admin");
//        return optional.map(s -> String.format(systemConfig.getTableauTaxCategoryUnreturnedTax(),
//                getTicket(s).orElse(StringUtils.EMPTY)));
//    }


    public Optional<String> getTableauTaxCategoryUnreturnedTax(HttpServletRequest request) {
        Optional<String> optional = Optional.of(getDDUserName(request));
        return optional.map(s -> String.format(systemConfig.getTableauTaxCategoryUnreturnedTax(), getTicket(s).orElse(StringUtils.EMPTY)));
    }

    public Optional<String> getTableauDistrictUnreturnedTax(HttpServletRequest request) {
        //TODO
        Optional<String> optional = Optional.of(getDDUserName(request));
        return optional.map(s -> String.format(systemConfig.getTableauDistrictUnreturnedTax(), getTicket(s).orElse(StringUtils.EMPTY)));
    }

    public Optional<String> getTableauUnreturnedAndReturnedTax(HttpServletRequest request) {
        Optional<String> optional = Optional.of(getDDUserName(request));
        return optional.map(s -> String.format(systemConfig.getTableauUnreturnedAndReturnedTax(), getTicket(s).orElse(StringUtils.EMPTY)));
    }

    public Optional<String> getTableauCostAnalysis(HttpServletRequest request) {
        Optional<String> optional = Optional.of(getDDUserName(request));
        return optional.map(s -> String.format(systemConfig.getTableauCostAnalysis(), getTicket(s).orElse(StringUtils.EMPTY)));
    }

    public Optional<String> getTableauDistrictProfitAndLoss(HttpServletRequest request) {
        Optional<String> optional = Optional.of(getDDUserName(request));
        return optional.map(s -> String.format(systemConfig.getTableauDistrictProfitAndLoss(), getTicket(s).orElse(StringUtils.EMPTY)));
    }

    public Optional<String> getTableauCompanyProfitAndLoss(HttpServletRequest request) {
        Optional<String> optional = Optional.of(getDDUserName(request));
        return optional.map(s -> String.format(systemConfig.getTableauCompanyProfitAndLoss(), getTicket(s).orElse(StringUtils.EMPTY)));
    }

    public Optional<String> getTableauDriverAndEmployee(HttpServletRequest request) {
        Optional<String> optional = Optional.of(getDDUserName(request));
        return optional.map(s -> String.format(systemConfig.getTableauDriverAndEmployee(), getTicket(s).orElse(StringUtils.EMPTY)));
    }

    public Optional<String> getTableauGmvAndSubsidy(HttpServletRequest request) {
        Optional<String> optional = Optional.of(getDDUserName(request));
        return optional.map(s -> String.format(systemConfig.getTableauGmvAndSubsidy(), getTicket(s).orElse(StringUtils.EMPTY)));
    }

    public Optional<String> getTableauFileArrangement(HttpServletRequest request) {
        Optional<String> optional = Optional.of(getDDUserName(request));
        return optional.map(s -> String.format(systemConfig.getTableauFileArrangement(), getTicket(s).orElse(StringUtils.EMPTY)));
    }

    public Optional<String> getTableauGlobalOverview(HttpServletRequest request) {
        Optional<String> optional = Optional.of(getDDUserName(request));
        return optional.map(s -> String.format(systemConfig.getTableauGlobalOverview(), getTicket(s).orElse(StringUtils.EMPTY)));
    }

    public Optional<String> getTableauGlobalBusiness(HttpServletRequest request) {
        Optional<String> optional = Optional.of(getDDUserName(request));
        return optional.map(s -> String.format(systemConfig.getTableauGlobalBusiness(), getTicket(s).orElse(StringUtils.EMPTY)));
    }

    public Optional<String> getTableauMexicanTax(HttpServletRequest request) {
        Optional<String> optional = Optional.of(getDDUserName(request));
        return optional.map(s -> String.format(systemConfig.getTableauMexicanTax(), getTicket(s).orElse(StringUtils.EMPTY)));
    }

    public Optional<String> getTableauAustralianTax(HttpServletRequest request) {
        Optional<String> optional = Optional.of(getDDUserName(request));
        return optional.map(s -> String.format(systemConfig.getTableauAustralianTax(), getTicket(s).orElse(StringUtils.EMPTY)));
    }

    public Optional<String> getTableauBrazilianTax(HttpServletRequest request) {
        Optional<String> optional = Optional.of(getDDUserName(request));
        return optional.map(s -> String.format(systemConfig.getTableauBrazilianTax(), getTicket(s).orElse(StringUtils.EMPTY)));
    }

    public Optional<String> getTableauOtherTaxAnalysis(HttpServletRequest request) {
        Optional<String> optional = Optional.of(getDDUserName(request));
        return optional.map(s -> String.format(systemConfig.getTableauOtherTaxAnalysis(), getTicket(s).orElse(StringUtils.EMPTY)));
    }

    //sso通过cookie获取登录的DD用户
    public String getDDUserName(HttpServletRequest request) {
        logger.info("进入 获取DD user的方法~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
        String ticket = getDDTicketByCookie( request);
        return findUsernameByDDTicket(ticket);
    }

    //通過cookie 取出ddTicket
    public String getDDTicketByCookie(HttpServletRequest request) {
        logger.info("进去获取cookie方法");
        Map<String, Cookie> cookieMap = ReadCookieMap( request);
        //TODO  修改token的名字到配置文件,判断ddTicket是否过期
        if (cookieMap.containsKey("ddTicket")) {

            return Optional.ofNullable(cookieMap.get("ddTicket")).map(s -> s.getValue()).orElse("");
        } else {
            return getDDTicket(Optional.ofNullable(cookieMap.get("code")).map(z -> z.getValue()).orElse(""));
        }
    }

    private String findUsernameByDDTicket(String ticket) {
        Assert.hasText(ticket, "empty ticket");

        DDUserInfoRes ddUserInfoRes = new DDUserInfoRes();
        try {
            String response = HttpUtil.post(getUserInfoUrl + "get_user_by_ticket", "ticket=" + ticket + "&app_id=" + appId, "application/x-www-form-urlencoded", "UTF-8", 10000, 10000);

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

        String username = Optional.ofNullable(ddUserInfoRes)
                .map(s -> s.getDdUserInfo())
                .map(n -> n.getUsername())
                .orElse("");
        return username;
    }

    /**
     * 将cookie封装到Map里面
     *
     * @return
     */
    private Map<String, Cookie> ReadCookieMap(HttpServletRequest request) {
        Map<String, Cookie> cookieMap = new HashMap<String, Cookie>();
        Cookie[] cookies = request.getCookies();
        if (null != cookies) {
            for (Cookie cookie : cookies) {
                cookieMap.put(cookie.getName(), cookie);
            }
        }
        return cookieMap;
    }

    //copy過來的 沒對象
    public String getDDTicket(String code) {
        try {
            JSONObject object;
            String ddResponse = HttpUtil.post(getUserInfoUrl + "check_code", "code=" + code + "&app_key=" + appKey + "&app_id=" + appId, "application/x-www-form-urlencoded", "UTF-8", 10000, 10000);
            object = JSONObject.parseObject(ddResponse);
            Map<String, Object> res = object.getInnerMap();
            int errno = (int) res.get("errno");
            if (errno != 0) {
                logger.warn(String.format("DDTicket get Failed:[%s]", object.toJSONString()));
                return null;
            } else {
                Map<String, String> dataMap = (Map) res.get("data");
                Cookie cookie = new Cookie("ddTicket", dataMap.get("ticket"));
                HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
                response.addCookie(cookie);
                return dataMap.get("ticket");
            }
        } catch (Exception e) {
        }
        return null;
    }
}