package com.lemon.lifecenter.common;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.spec.AlgorithmParameterSpec;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Random;
import java.util.UUID;

import javax.crypto.Cipher;
import javax.crypto.Mac;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class LifeCenterFunction {
    public static String setURLEncode(String content, String lngType) throws UnsupportedEncodingException {
        return URLEncoder.encode(content, lngType);
    }

    public static String setURLDecode(String content, String lngType) throws UnsupportedEncodingException {
        return URLDecoder.decode(content, lngType);
    }

    public static String aesEncrypt(String encKey, byte[] iv, String paramInput) throws Exception {
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        SecretKeySpec key = new SecretKeySpec(encKey.getBytes("UTF-8"), "AES");

        cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));

        byte[] cipherText = cipher.doFinal(paramInput.getBytes("UTF-8"));

        return Base64.getEncoder().encodeToString(cipherText);
    }

    public static String aesDecrypt(String encKey, byte[] iv, String paramInput) throws Exception {
        byte[] textBytes = Base64.getDecoder().decode(paramInput);
        AlgorithmParameterSpec ivSpec = new IvParameterSpec(iv);
        SecretKeySpec newKey = new SecretKeySpec(encKey.getBytes("UTF-8"), "AES");

        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, newKey, ivSpec);

        return new String(cipher.doFinal(textBytes), "UTF-8");
    }

    public static ArrayList<HashMap<String, String>> parseJSON(String jsonString) {
        ArrayList<HashMap<String, String>> rtn = new ArrayList<HashMap<String, String>>();

        try {
            JSONArray array = new JSONArray(jsonString);

            for (int i = 0; i < array.length(); i++) {
                HashMap<String, String> map = new HashMap<String, String>();

                JSONObject object = array.getJSONObject(i);
                Iterator<?> keys = object.keys();

                while (keys.hasNext()) {
                    String key = (String) keys.next();
                    String val = "";

                    if (object.isNull(key)) {
                        val = "";
                    } else {
                        if (object.get(key) instanceof Integer) {
                            val = String.valueOf(object.getInt(key));
                        } else if (object.get(key) instanceof Long) {
                            val = String.valueOf(object.getLong(key));
                        } else if (object.get(key) instanceof Double) {
                            val = String.valueOf(object.getDouble(key));
                        } else {
                            val = object.getString(key).equals(null) ? "" : object.getString(key);
                        }
                    }

                    map.put(key, val);
                }

                rtn.add(i, map);

                map = null;
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }

        return rtn;
    }

    public static String getRandomUUID() {
        return UUID.randomUUID().toString().replaceAll("-", "");
    }

    public static String exportOnlyNumber(String input) {
        return input.replaceAll("[^0-9?!\\.]", "");
    }

    public static String getNow() {
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = new Date();

        return dateFormat.format(date);
    }

    public static String getNow(String format) {
        DateFormat dateFormat = new SimpleDateFormat(format);
        Date date = new Date();

        return dateFormat.format(date);
    }

    public static long getNowUnixTimeStamp() {
        return System.currentTimeMillis() / 1000;
    }

    public static long setFormatUnixTimeStamp(String data) {
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        long timeStamp = 0;

        try {
            long time = dateFormat.parse(data).getTime();
            timeStamp = time / 1000;
        } catch (ParseException e) {
            e.printStackTrace();
        }

        return timeStamp;
    }

    public static String setFormatDateFromUnixTimeStamp(Date data) {
        SimpleDateFormat transFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        return transFormat.format(data);
    }

    public static String getRandomNumber(int maxSize) {
        Random rand = new Random();
        String code = "";

        for (int i = 0; i < maxSize; i++) {
            code += rand.nextInt(9);
        }

        return code;
    }

    public static void scriptMessage(HttpServletResponse response, String script) {
        response.setContentType("text/html; charset=UTF-8");
        PrintWriter out;

        try {
            out = response.getWriter();
            out.println("<script>" + script + "</script>");
            out.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static String getRemoteAddr(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");

        if (ip == null) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null) {
            ip = request.getRemoteAddr();
        }

        return ip;
    }

    public static String setPhoneFormat(String number) {
        StringBuilder sb = new StringBuilder(15);
        StringBuilder temp = new StringBuilder(number);
        int tempLength = temp.length();

        if (tempLength == 3) {
            sb.append(number);
        } else {
            while (tempLength < 10) {
                temp.insert(0, "0");
            }

            char[] chars = temp.toString().toCharArray();

            int size = chars.length;

            if (size < 11) {
                for (int i = 0; i < size; i++) {
                    if (i == 3) {
                        sb.append("-");
                    } else if (i == 6) {
                        sb.append("-");
                    }

                    sb.append(chars[i]);
                }
            } else {
                for (int i = 0; i < size; i++) {
                    if (i == 3) {
                        sb.append("-");
                    } else if (i == 7) {
                        sb.append("-");
                    }

                    sb.append(chars[i]);
                }
            }
        }

        return sb.toString();
    }
    
    public static String removeTag(String html) throws Exception {
        return html.replaceAll("<(/)?([a-zA-Z]*)(\\s[a-zA-Z]*=[^>]*)?(\\s)*(/)?>", "");
    }
    
    public static String getSalt() {
        String uniqId = "";
        Random randomGenerator = new Random();

        // length - set the unique Id length
        for (int length = 1; length <= 10; ++length) {
            int randomInt = randomGenerator.nextInt(10); // digit range from 0 - 9
            uniqId += randomInt + "";
        }

        return uniqId;
    }
    
    public static String getTimestamp() {
        long timestamp_long = System.currentTimeMillis() / 1000;
        String timestamp = Long.toString(timestamp_long);
        return timestamp;
    }
    
    private static final Logger logger = LoggerFactory.getLogger(LifeCenterFunction.class);
    public static String getSignature(String apiSecret, String salt, String timestamp) throws Exception {
        String signature = "";

        try {
            String temp = timestamp + salt;
            logger.error("temp -- > " + temp);
            SecretKeySpec keySpec = new SecretKeySpec(apiSecret.getBytes(), "HmacSHA256");
            Mac mac = Mac.getInstance("HmacSHA256");
            mac.init(keySpec);

            // 바이너리를 hex로 변환
            byte[] result = mac.doFinal(temp.getBytes());
            char[] hexArray = "0123456789ABCDEF".toCharArray();
            char[] hexChars = new char[result.length * 2];

            for (int i = 0; i < result.length; i++) {
                int positive = result[i] & 0xff;
                hexChars[i * 2] = hexArray[positive >>> 4];
                hexChars[i * 2 + 1] = hexArray[positive & 0x0F];
            }
            signature = new String(hexChars);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return signature.toLowerCase();
    }
    
    public static String httpUrlConnection(String apiUrl, HashMap<String, String> hash) {
        String result = "";
        URL url;
        try {
            url = new URL(apiUrl);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            conn.setRequestProperty("Accept", "application/json");
            conn.setRequestMethod("POST"); // post방식 통신
            conn.setDoOutput(true);       // 쓰기모드 지정
            conn.setDoInput(true);        // 읽기모드 지정
            conn.setUseCaches(false);     // 캐싱데이터를 받을지 안받을지
            conn.setDefaultUseCaches(false); // 캐싱데이터 디폴트 값 설정
            conn.setReadTimeout(10000); // 타임아웃 10초
            
            OutputStream os = conn.getOutputStream(); // 서버로 보내기 위한 출력 스트림
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os, "UTF-8")); // UTF-8로 전송
            bw.write(getPostString(hash)); // 매개변수 전송
            bw.flush();
            bw.close();
            os.close();

            InputStream is = conn.getInputStream();   //데이타를 받기위 구멍을 열어준다
            StringBuilder builder = new StringBuilder();   //문자열을 담기 위한 객체
            BufferedReader reader = new BufferedReader(new InputStreamReader(is,"UTF-8"));  //문자열 셋 세팅

            String line;
            while ((line = reader.readLine()) != null) {
                builder.append(line+ "\n");
            }

//            logger.error("httpUrlConnection Result -- > " + builder.toString());
            result = builder.toString();

            conn.disconnect();
        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        
        return result;
    }
    
    private static String getPostString(HashMap<String, String> map) {
        StringBuilder result = new StringBuilder();
        boolean first = true; // 첫 번째 매개변수 여부

        for (Map.Entry<String, String> entry : map.entrySet()) {
            if (first)
                first = false;
            else // 첫 번째 매개변수가 아닌 경우엔 앞에 &를 붙임
                result.append("&");

            try { // UTF-8로 주소에 키와 값을 붙임
                result.append(URLEncoder.encode(entry.getKey(), "UTF-8"));
                result.append("=");
                result.append(URLEncoder.encode(entry.getValue(), "UTF-8"));
            } catch (UnsupportedEncodingException ue) {
                ue.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return result.toString();
    }

    public static String phone(String src) {
        if (src == null) {
          return "";
        }
        if (src.length() == 8) {
          return src.replaceFirst("^([0-9]{4})([0-9]{4})$", "$1-$2");
        } else if (src.length() == 12) {
          return src.replaceFirst("(^[0-9]{4})([0-9]{4})([0-9]{4})$", "$1-$2-$3");
        }
        return src.replaceFirst("(^02|[0-9]{3})([0-9]{3,4})([0-9]{4})$", "$1-$2-$3");
    }
    
}
