package kr.co.jinwoosi.clfd.clfd.sms.service;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import kr.co.jinwoosi.clfd.clfd.sms.vo.SmsState;
import kr.co.jinwoosi.clfd.clfd.sms.vo.SmsVo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Random;

@Service
public class SmsService {

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

    @Value("${sms.api.key}")
    private String smsApiKey;

    @Value("${sms.api.sendNumber}")
    private String smsApiSendNumber;

    public SmsVo sendSmsAuthKey(String receiveNumber) {
        String message = "인증번호 전송에 실패하였습니다.";
        try {
            if (StringUtils.isEmpty(receiveNumber)) {
                throw new IllegalArgumentException();
            }

            String smsAuthKey = getSmsAuthKey();
            String msg = "[컬러푸드] 인증번호 ["+smsAuthKey+"]를 입력해 주세요.";
            URL url = new URL(smsApiUrl);
            Map<String, Object> params = new LinkedHashMap<>();
            params.put("api_key", smsApiKey);
            params.put("msg", msg);
            params.put("callback", smsApiSendNumber);
            params.put("dstaddr", receiveNumber);
            params.put("send_reserve", "0");

            StringBuilder postData = new StringBuilder();
            for (Map.Entry<String, Object> param : params.entrySet()) {
                if (postData.length() != 0) postData.append('&');
                postData.append(URLEncoder.encode(param.getKey(), "UTF-8"));
                postData.append('=');
                postData.append(URLEncoder.encode(String.valueOf(param.getValue()), "UTF-8"));
            }
            byte[] postDataBytes = postData.toString().getBytes("UTF-8");

            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            conn.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length));
            conn.setDoOutput(true);

            conn.getOutputStream().write(postDataBytes);

            Reader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));

            StringBuilder sb = new StringBuilder();
            for (int c; (c = in.read()) >= 0; ) {
                sb.append((char) c);
            }
            String response = sb.toString();

            ObjectMapper mapper = new ObjectMapper();
            JsonNode root = mapper.readTree(response);
            String returnCode = root.get("result").asText();
            if (returnCode.equals("100")) {
                return SmsVo.builder()
                        .smsState(SmsState.SUCCESS)
                        .smsAuthKey(smsAuthKey)
                        .message("인증번호를 전송하였습니다.")
                        .build();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            message = "휴대폰 번호를 입력해주세요.";
        }

        return SmsVo.builder()
                .smsState(SmsState.FAIL)
                .message(message)
                .build();
    }

    /**
     * SMS 인증 번호를 생성한다.
     * @return SMS 인증번호
     */
    public String getSmsAuthKey() {
        int AUTH_KEY_LENGTH = 6;
        Random rand = new Random();
        String numStr = "";
        for(int i=0;i<AUTH_KEY_LENGTH;i++) {
            String ran = Integer.toString(rand.nextInt(9)+1);
            numStr += ran;
        }
        return numStr;
    }

}
