package main

import (
	"encoding/json"
	"io/ioutil"
	"log"
	"net/http"
	"time"
)

type crmLeadInfo struct {
	ID                         string   `json:"id"`
	Name                       string   `json:"name,omitempty"`
	Deleted                    bool     `json:"deleted,omitempty"`
	SalutationName             string   `json:"salutationName,omitempty"`
	FirstName                  string   `json:"firstName,omitempty"`
	LastName                   string   `json:"lastName,omitempty"`
	Title                      string   `json:"title,omitempty"`
	Status                     string   `json:"status,omitempty"`
	Source                     string   `json:"source,omitempty"`
	Industry                   string   `json:"industry,omitempty"`
	OpportunityAmount          int      `json:"opportunityAmount,omitempty"`
	Website                    string   `json:"website,omitempty"`
	AddressStreet              string   `json:"addressStreet,omitempty"`
	AddressCity                string   `json:"addressCity,omitempty"`
	AddressState               string   `json:"addressState,omitempty"`
	AddressCountry             string   `json:"addressCountry,omitempty"`
	AddressPostalCode          string   `json:"addresPostalCode,omitempty"`
	EmailAddress               string   `json:"emailAddress,omitempty"`
	PhoneNumber                string   `json:"phoneNumber,omitempty"`
	DoNotCall                  bool     `json:"doNotCall,omitempty"`
	Description                string   `json:"description,omitempty"`
	CreatedAt                  string   `json:"createdAt,omitempty"`
	ModifiedAt                 string   `json:"ModifiedAt,omitempty"`
	AccountName                string   `json:"accountName,omitempty"`
	Password                   string   `json:"password,omitempty"`
	WechatHitxyID              string   `json:"wechat_hitxy_id,omitempty"`
	Verifier                   []string `json:"verifier,omitempty"`
	OpportunityAmountCurrency  string   `json:"opportunityAmountCurrency,omitempty"`
	OpportunityAmountConverted int      `json:"opportunityAmountConverted,omitempty"`
	EmailAddressData           []struct {
		EmailAddress string `json:"emailAddress,omitempty"`
		Lower        string `json:"lower,omitempty"`
		Primary      bool   `json:"primary,omitempty"`
		OptOut       bool   `json:"optOut,omitempty"`
		Invalid      bool   `json:"invalid,omitempty"`
	} `json:"emailAddressData,omitempty"`
	PhoneNumberData []struct {
		PhoneNumber string `json:"phoneNumber,omitempty"`
		Primary     bool   `json:"primary,omitempty"`
		Type        string `json:"type,omitempty"`
	} `json:"phoneNumberData,omitempty"`
	CreatedByID          string `json:"createdById,omitempty"`
	CreatedByName        string `json:"createdByName,omitempty"`
	ModifiedByID         string `json:"modifiedById,omitempty"`
	ModifiedByName       string `json:"modifiedByName,omitempty"`
	AssignedUserID       string `json:"assignedUserId,omitempty"`
	AssignedUserName     string `json:"assignedUserName,omitempty"`
	CampaignID           string `json:"campaignId,omitempty"`
	CreatedAccountID     string `json:"createdAccountId,omitempty"`
	CreatedContactID     string `json:"createdContactId,omitempty"`
	CreatedOpportunityID string `json:"createdOpportunityId,omitempty"`
}

type crmSearchLead struct {
	Total int           `json:"total"`
	List  []crmLeadInfo `json:"list"`
}

func (m *crmLeadInfo) getCreatedAt() (r time.Time) {
	layout := m.getTimeLayout()
	r, _ = time.Parse(layout, m.CreatedAt)
	return
}

func (m *crmLeadInfo) setCreatedAt(v time.Time) string {
	layout := m.getTimeLayout()
	m.CreatedAt = v.Format(layout)
	return m.CreatedAt
}

func (m *crmLeadInfo) getModifiedAt() (r time.Time) {
	layout := m.getTimeLayout()
	r, _ = time.Parse(layout, m.ModifiedAt)
	return
}

func (m *crmLeadInfo) setModifiedAt(v time.Time) string {
	layout := m.getTimeLayout()
	m.ModifiedAt = v.Format(layout)
	return m.ModifiedAt
}

func (m *crmLeadInfo) getTimeLayout() string {
	return "2006-01-02 15:04:05"
}

func crmFindOpenID(openID string) (info crmLeadInfo, found bool, err error) {
	found = false
	req, err := http.NewRequest("GET", "https://c.hitxy.org.au/api/v1/Lead", nil)
	if err != nil {
		log.Println("crmGetRecord: cannot form good http Request")
		log.Print(err)
		return
	}

	//auth header
	req.Header.Set("Authorization", crmAuthHeader())
	req.Header.Set("Accept", "application/json, text/javascript, */*; q=0.01")
	req.Header.Set("Content-Type", "application/json")

	//query string
	q := req.URL.Query()
	q.Add("maxSize", "20")
	q.Add("maxSize", "0")
	q.Add("sortBy", "createdAt")
	q.Add("asc", "false")
	q.Add("where[0][type]", "equals")
	q.Add("where[0][attribute]", "wechat_hitxy_id")
	q.Add("where[0][value]", openID)
	req.URL.RawQuery = q.Encode()

	// dump, err := httputil.DumpRequest(req, true)
	// if err != nil {
	// 	log.Fatal(err)
	// }
	// fmt.Printf("dump : %q", dump)

	client := &http.Client{}
	r, err := client.Do(req)

	if err != nil {
		return
	}
	defer r.Body.Close()

	b, _ := ioutil.ReadAll(r.Body)
	search := crmSearchLead{}
	err = json.Unmarshal(b, &search)

	if err != nil || search.Total <= 0 {
		return
	}

	if search.Total > 1 {
		log.Printf("ERROR It's wrong to have multiple record for same wechat id %s", openID)
		for _, v := range search.List {
			log.Println(v)
		}
		return
	}

	//we successfully reach here
	info = search.List[0]
	found = true
	return
}

//crmPrepareAttachmentHTTPHeader   when uploading a file, we need its mime, auth header, etc.
func crmPrepareLeadUploadHTTPHeader() (headers map[string]string) {
	headers = map[string]string{}
	headers["Authorization"] = crmAuthHeader()
	headers["Accept"] = "application/json"
	headers["Content-Type"] = "application/json"
	return headers
}
