package icshttpclient

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"time"

	"gitlab.com/cinnamon/voiceagent/icserror"
	"gitlab.com/cinnamon/voiceagent/icslog"
)

type IcsHttpClient struct {
	Method  string
	URL     string
	Request *http.Request
	http.Client
}

type ServiceInfoBody struct {
	CustTel string `json:"custTel"`
}

type ServiceInfoResp struct {
	ServiceInfoMent string            `json:"serviceInfoMent"`
	ServiceInfo     []ServiceInfoJSON `json:"serviceInfo"`
}

type ServiceInfoJSON struct {
	OprMngCode string `json:"oprMngCode"`
	Dtmf       int    `json:"dtmf"`
}

type ProcessBody struct {
	Token          string `json:"token"`
	OprMngCode     string `json:"oprMngCode"`
	Method         string `json:"method"`
	TalkText       string `json:"talkText"`
	CallID         string `json:"callId"`
	DNIS           string `json:"dnis"`
	TelNO          string `json:"telNo"`
	MentType       string `json:"mentType"`
	RecordFilePath string `json:"recordFilePath"`
}

type ProcessResp struct {
	ResultCode    int      `json:"resultCode"`
	Token         string   `json:"token"`
	Action        string   `json:"action"`
	AnnounceMents string   `json:"announceMents"`
	Data          DataJSON `json:"data"`
}

type DataJSON struct {
	BargeIn      string `json:"bargeIn"`
	RecodingFile string `json:"recodingFile"`
	STTMaxTime   int    `json:"sttMaxTime"`
	MaxDigit     int    `json:"maxDigit"`
	MinDigit     int    `json:"minDigit"`
	DigitTerm    int    `json:"digitTerm"`
	TelNo        string `json:"telNo"`
}

func NewIcsHttpClient(method, url string, body io.Reader) *IcsHttpClient {
	c := &IcsHttpClient{Method: method, URL: url}
	r, err := http.NewRequest(method, url, body)
	if err != nil {
		fmt.Println("NewHttpClient", err)
		return nil
	}
	c.Request = r
	c.SetTimeout(time.Millisecond * 1000 * 5)

	return c
}

func (c *IcsHttpClient) SetTimeout(timeout time.Duration) {
	c.Timeout = timeout
}

///platform/api/call/serviceInfo
func PostServiceInfo(url string, custTel string) (svcInfo *ServiceInfoResp) {
	svcInfoBody := ServiceInfoBody{CustTel: custTel}
	b, err := json.Marshal(svcInfoBody)
	if err != nil {
		//fmt.Println(">>> json marshal error", err)
		return nil
	}
	body := bytes.NewBuffer(b)

	/*
		fmt.Println("url", url)
		fmt.Println("body", body)
	*/
	client := NewIcsHttpClient("POST", url, body)
	if client == nil {
		fmt.Println("http client error")
		return nil
	}
	client.Request.Header.Add("Content-Type", "application/json;charset=UTF-8")
	resp, err := client.Do(client.Request)
	if err != nil {
		fmt.Println("http request error", err)
		return nil
	}
	//resBody := make([]byte, resp.ContentLength)
	//resp.Body.Read(resBody)
	resBody, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(err)
		return nil
	}
	defer resp.Body.Close()
	/*
		fmt.Println("Response>")
		fmt.Println(string(resBody))
		fmt.Println("====================")

		fmt.Printf("%+v\n", resp)
	*/

	err = json.Unmarshal(resBody, &svcInfo)
	if err != nil {
		fmt.Printf("%s - %+v\n", err, resBody)
		return nil
	}
	//ment = svcInfo.ServiceInfoMent
	//fmt.Println("svc ment", svcInfo.ServiceInfoMent)

	return
}

///platform/api/call/process
func PostProcess(url, method string, sttResult, custTel, oprMngCode, callID string, dnis string, token string, sttFilePath string) (processResp *ProcessResp) {
	l := icslog.GetIcsLog()
	/*
		type ProcessBody struct {
			Token          string `json:"token"`
			OprMngCode     string `json:"oprMngCode"`
			Method         string `json:"method"`
			TalkText       string `json:"talkText"`
			CallID         string `json:"callID"`
			TelNO          string `json:"telNo"`
			MentType       string `json:"mentType"`
			RecordFilePath string `json:"recordFilePath"`
		}
	*/
	processBody := ProcessBody{
		Token:          token,
		OprMngCode:     oprMngCode,
		Method:         method,
		TalkText:       sttResult,
		CallID:         callID,
		DNIS:           dnis,
		TelNO:          custTel,
		MentType:       "VOICE",
		RecordFilePath: sttFilePath,
	}
	b, err := json.Marshal(processBody)
	if err != nil {
		//fmt.Println(">>> json marshal error", err)
		return nil
	}
	body := bytes.NewBuffer(b)

	/*
		fmt.Println("url", url)
		fmt.Println("body", body)
	*/
	client := NewIcsHttpClient("POST", url, body)
	if client == nil {
		//fmt.Println("http client error")
		return nil
	}
	client.Request.Header.Add("Content-Type", "application/json;charset=UTF-8")
	l.Printf(icslog.LOG_LEVEL_DEBUG2, -1, "Post Request: %+v", client.Request)

	////////////////////////////////////////////
	resp, err := client.Do(client.Request)
	if err != nil {
		//fmt.Println("http request error", err)
		return nil
	}
	//fmt.Printf("client request : %+v\n%+v\n", client.Request, string(b))
	//resBody := make([]byte, resp.ContentLength)
	//resp.Body.Read(resBody)
	resBody, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		//fmt.Println(err)
		return nil
	}
	/*
		fmt.Println("\nResponse>")
		fmt.Println(string(resBody))
		fmt.Println("====================")

		fmt.Printf("%+v\n", resp)
	*/

	resp.Body.Close()
	////////////////////////////////////////////

	//var svcInfo ServiceInfoResp
	json.Unmarshal(resBody, &processResp)
	//fmt.Printf("process resp: %+v\n", processResp)

	return
}

// add client info
func NewPostProcess(url, method string, sttResult, custTel, oprMngCode, callID string, dnis string, token string, sttFilePath string) (cleint *IcsHttpClient) {
	l := icslog.GetIcsLog()
	/*
		type ProcessBody struct {
			Token          string `json:"token"`
			OprMngCode     string `json:"oprMngCode"`
			Method         string `json:"method"`
			TalkText       string `json:"talkText"`
			CallID         string `json:"callID"`
			TelNO          string `json:"telNo"`
			MentType       string `json:"mentType"`
			RecordFilePath string `json:"recordFilePath"`
		}
	*/
	processBody := ProcessBody{
		Token:          token,
		OprMngCode:     oprMngCode,
		Method:         method,
		TalkText:       sttResult,
		CallID:         callID,
		DNIS:           dnis,
		TelNO:          custTel,
		MentType:       "VOICE",
		RecordFilePath: sttFilePath,
	}
	b, err := json.Marshal(processBody)
	if err != nil {
		//fmt.Println(">>> json marshal error", err)
		return nil
	}
	body := bytes.NewBuffer(b)

	/*
		fmt.Println("url", url)
		fmt.Println("body", body)
	*/
	client := NewIcsHttpClient("POST", url, body)
	if client == nil {
		//fmt.Println("http client error")
		return nil
	}
	client.Request.Header.Add("Content-Type", "application/json;charset=UTF-8")
	l.Printf(icslog.LOG_LEVEL_DEBUG2, -1, "Post Request: %+v", client.Request)

	return client
}

// resp body
func ClientDo(request *IcsHttpClient) (resBody []byte, cerr *icserror.IcsError) {
	resp, err := request.Do(request.Request)
	if err != nil {
		//fmt.Println("http request error", err)
		icserror.ICSERRHTTPClientResponse.SetError(err)
		return nil, icserror.ICSERRHTTPClientResponse
	}
	resBody, err = ioutil.ReadAll(resp.Body)
	defer resp.Body.Close()
	if err != nil {
		icserror.ICSERRHTTPClientResponse.SetError(err)
		return nil, icserror.ICSERRHTTPClientResponse
	}

	return resBody, nil
}
