package main

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

type crmdLead struct {
	crmdEntityBase
	//ID   string `json:"id,omitempty"`
	//Name string `json:"name,omitempty"`
	//Deleted           bool   `json:"deleted,omitempty"`
	AvatarID          string `json:"avatarId,omitempty"`
	AvatarName        string `json:"avatarName,omotempty"`
	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:"wechatOpenID,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"`

	ForceDuplicate bool `json:"forceDuplicate,omitempty"` //when purposely creating duplicated record, we need to set this to true
}

type crmdSearchLead struct {
	Total int        `json:"total"`
	List  []crmdLead `json:"list"`
}

func crmFindLeadByOpenID(openID string) (info crmdLead, found bool, err error) {
	total, list, err := crmFindEntityByAttr("Lead", "wechatOpenID", openID)
	if err != nil {
		return
	}

	if total == 1 {
		found = true
		info = list.([]crmdLead)[0]
		return
	}
	found = false
	if total > 1 {

		msg := fmt.Sprintf("wechatOpenID %s has %d record", openID, total)
		log.Printf(msg)
	}
	return
}

func crmGetLead(id string) (r crmdLead, err error) {
	entity, err := crmGetEntity("Lead", id)
	r = entity.(crmdLead)
	return
}

func crmPatchLeadInfo(newInfo crmdLead) (updatedLead crmdLead, err error) {
	b, err := json.Marshal(newInfo)
	if err != nil {
		log.Printf("Failed to Patch new Info for Lead")
		log.Println(newInfo)
		return
	}
	newEntity, err := crmUpdateEntity("Lead", newInfo.ID, b)
	if err != nil {
		return
	}
	updatedLead, ok := newEntity.(crmdLead)

	if !ok {
		err = errors.New("Update Lead result in wrong entityType")
	}
	return
}

func crmLeadSetStatusNew(id string) {
	crmLeadSetStatus(id, "New")
}

func crmLeadSetStatusDead(id string) {
	crmLeadSetStatus(id, "Dead")
}

func crmLeadSetStatus(id string, status string) {
	newLead := crmdLead{}
	newLead.ID = id
	newLead.Status = status
	crmPatchLeadInfo(newLead)
}

//WechatUserList 超过一万个也可能呢。
//Decode Wechat user List {"total":2,"count":2,"data":{"openid":["","OPENID1","OPENID2"]},"next_openid":"NEXT_OPENID"}
type WechatUserList struct {
	Total int `json:"total,omitempty"`
	Count int `json:"count,omitempty"`
	Data  struct {
		OpenID []string `json:"openid"`
	} `json:"data,omitempty"`
	NextOpenID string `json:"next_openid,omitempty"`
}

func importExistingWechatUserAsLead() {
	//当公众号关注者数量超过10000时，可通过填写next_openid的值，从而多次拉取列表的方式来满足需求。
	atk, _ := GetAccessToken()
	nextOpenID := ""
	url := fmt.Sprintf("https://api.weixin.qq.com/cgi-bin/user/get?access_token=%s&next_openid=%s", atk, nextOpenID)

	req, err := http.NewRequest("GET", url, nil)
	var myClient = &http.Client{Timeout: 20 * time.Second}

	r, err := myClient.Do(req)
	if err != nil {
		log.Printf("Fail to get URL: %s", req.RequestURI)
		log.Println(err)
	}
	defer r.Body.Close()

	jsonB, err := ioutil.ReadAll(r.Body)

	users := WechatUserList{}
	err = json.Unmarshal(jsonB, &users)
	if err != nil {
		return
	}

	for _, openID := range users.Data.OpenID {
		log.Println(openID)
		_, found, err := crmFindLeadByOpenID(openID)

		if !found && err == nil {
			info := WechatUserInfo{}
			info.getUserInfo(openID, "zh_CN")
			info.registerNewLeadWithInfo(openID)
		}
	}
}
