package services

import (
	"crypto/tls"
	"encoding/base64"
	"encoding/json"
	"fmt"
	openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
	ocr20191230 "github.com/alibabacloud-go/ocr-20191230/v3/client"
	util "github.com/alibabacloud-go/tea-utils/v2/service"
	"github.com/alibabacloud-go/tea/tea"
	rhttp "github.com/rdlucklib/rdluck_tools/http"
	"hongze/hz_crm_api/models/company"
	"hongze/hz_crm_api/models/cygx"
	"hongze/hz_crm_api/utils"
	"io"
	"io/ioutil"
	"net/http"
	"strings"
	"time"
)

const (
	AlAppKey    = "203889624"
	AlAppSecret = "voampGGl0yGNx5xA1sZdmZlV2EiBct2P"
	AlAppCode   = "22553c4ba74545568aba70ac6cfd441d"
)

var (
	//文档 https://market.aliyun.com/apimarket/detail/cmapi013591?spm=5176.product-detail.detail.4.6d4f3dcaS0qPFI&endpoint=a3dd145f3865492ba6f02d0c09dd00a1
	AliyunOcrBusinessCardCode = "22553c4ba74545568aba70ac6cfd441d" // 阿里云OCR名片识别的code
)

type OcrItem struct {
	Image string `json:"image"`
}

type OcrResult struct {
	Addr               []string `json:"addr"`
	Company            []string `json:"company"`
	Success            bool     `json:"success"`
	TelCell            []string `json:"tel_cell"`
	Departments        []string `json:"departments"`
	Name               string   `json:"name"`
	OfficePhoneNumbers []string `json:"office_phone_numbers"`
	Titles             []string `json:"titles"`
}

// /ocr_business_card.json
func AliyunBusinessCard(imgUrl string) (result *OcrResult, err error) {
	postUrl := `https://dm-57.data.aliyun.com/rest/160601/ocr/ocr_business_card.json`

	imgBody, err := rhttp.Get(imgUrl)
	if err != nil {
		return
	}
	imageBase64 := base64.StdEncoding.EncodeToString(imgBody)

	item := new(OcrItem)
	item.Image = imageBase64
	jsonBody, err := json.Marshal(item)
	if err != nil {
		fmt.Println("json.Marshal Err:" + err.Error())
		return
	}
	tr := &http.Transport{
		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
	}
	client := &http.Client{Transport: tr}
	req, err := http.NewRequest("POST", postUrl, strings.NewReader(string(jsonBody)))
	if err != nil {
		fmt.Println("err:" + err.Error())
		return
	}
	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("Authorization", "APPCODE "+AlAppCode)
	resp, err := client.Do(req)
	if err != nil {
		fmt.Println("client.Do Err:" + err.Error())
		return
	}
	fmt.Println("resp")
	fmt.Println(resp)
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println("err:" + err.Error())
		return
	}
	fmt.Println("body:", string(body))
	utils.FileLog.Info(fmt.Sprintf("aliyun card;imgUrl:%s; Body:%s", imgUrl, string(body)))
	err = json.Unmarshal(body, &result)
	return
}

// AliyunBusinessCardOcr 阿里云的ocr识别
func AliyunBusinessCardOcr(imgUrl string) (result OcrResult, err error) {
	config := &openapi.Config{
		// 2、"YOUR_ACCESS_KEY_ID", "YOUR_ACCESS_KEY_SECRET" 的生成请参考https://help.aliyun.com/document_detail/175144.html
		// 如果您是用的子账号AccessKey,还需要为子账号授予权限AliyunVIAPIFullAccess,请参考https://help.aliyun.com/document_detail/145025.html
		// 您的 AccessKey ID
		AccessKeyId: tea.String(utils.AccessKeyId),
		// 您的 AccessKey Secret
		AccessKeySecret: tea.String(utils.AccessKeySecret),
	}
	// 3、访问的域名。注意:这个地方需要求改为相应类目的域名,参考:https://help.aliyun.com/document_detail/143103.html
	config.Endpoint = tea.String("ocr.cn-shanghai.aliyuncs.com")
	// 4、这里只是以ocr为例,其他能力请使用相应类目的包

	client, err := ocr20191230.NewClient(config)
	if err != nil {
		return
	}
	httpClient := http.Client{}
	file, _ := httpClient.Get(imgUrl)

	// 5、这里只是以ocr的RecognizeBankCard为例,其他能力请使用相应类目的包和类
	recognizeBusinessCardAdvanceRequest := &ocr20191230.RecognizeBusinessCardAdvanceRequest{
		ImageURLObject: file.Body,
	}
	runtime := &util.RuntimeOptions{}
	// 6、这里只是以ocr的RecognizeBankCard为例,其他能力请使用相应类目的包和类,注意RecognizeBankCardWithOptions也需要改成对应能力的方法名。方法名是根据能力名称按照一定规范形成的,如能力名称为SegmentCommonImage,对应方法名应该为SegmentCommonImageWithOptions。
	recognizeBusinessCardResponse, err := client.RecognizeBusinessCardAdvance(recognizeBusinessCardAdvanceRequest, runtime)

	if err != nil {
		// 获取整体报错信息
		//fmt.Println(err.Error())
		utils.FileLog.Info(fmt.Sprintf("aliyun card;imgUrl:%s; err:%s", imgUrl, err))
		return
	}

	// 获取整体结果
	//fmt.Println(recognizeBusinessCardResponse)
	//// 获取单个字段,这里只是一个例子,具体能力下的字段需要看具体能力的文档
	//fmt.Println(recognizeBusinessCardResponse.Body.Data.Name)

	// 地址
	for _, v := range recognizeBusinessCardResponse.Body.Data.Addresses {
		result.Addr = append(result.Addr, *v)
	}
	// company
	for _, v := range recognizeBusinessCardResponse.Body.Data.Companies {
		result.Company = append(result.Company, *v)
	}
	// tel_cell
	for _, v := range recognizeBusinessCardResponse.Body.Data.CellPhoneNumbers {
		result.TelCell = append(result.TelCell, *v)
	}
	// Departments
	for _, v := range recognizeBusinessCardResponse.Body.Data.Departments {
		result.Departments = append(result.Departments, *v)
	}
	// OfficePhoneNumbers
	for _, v := range recognizeBusinessCardResponse.Body.Data.OfficePhoneNumbers {
		result.OfficePhoneNumbers = append(result.OfficePhoneNumbers, *v)
	}
	// Titles
	for _, v := range recognizeBusinessCardResponse.Body.Data.Titles {
		result.Titles = append(result.Titles, *v)
	}
	if recognizeBusinessCardResponse.Body.Data.Name != nil {
		result.Name = *recognizeBusinessCardResponse.Body.Data.Name
	}
	result.Success = true

	return
}

// 阿里云名片识别返回类
type OcrBusinessCardResult struct {
	TelCell    []string `json:"tel_cell"`
	Success    bool     `json:"success"`
	Name       string   `json:"name"`
	Company    []string `json:"company"`
	Addr       []string `json:"addr"`
	Department []string `json:"department"`
	Title      []string `json:"title"`
	RequestID  string   `json:"request_id"`
	Email      []string `json:"email"`
	TelWork    []string `json:"tel_work"`
}

// 阿里云名片识别更换2024-01-02
func AliyunOcrBusinessCard(imageurl string) (result *OcrBusinessCardResult, errMsg string, err error) {
	url := "https://bizcard.market.alicloudapi.com/rest/160601/ocr/ocr_business_card.json"
	method := "POST"

	payload := strings.NewReader(`{
    "image":"` + imageurl + `"
}`)
	client := &http.Client{}
	req, err := http.NewRequest(method, url, payload)

	if err != nil {
		fmt.Println(err)
		return
	}
	req.Header.Add("Authorization", "APPCODE "+AliyunOcrBusinessCardCode)
	req.Header.Add("Content-Type", "application/json")

	res, err := client.Do(req)
	if err != nil {
		fmt.Println(err)
		return
	}
	defer res.Body.Close()

	body, err := io.ReadAll(res.Body)
	if err != nil {
		fmt.Println(err)
		return
	}
	err = json.Unmarshal(body, &result)
	if err != nil {
		fmt.Println(err)
		return
	}

	//处理返回的手机号格式,并进行数据合并
	var telCell []string
	if len(result.TelCell) > 0 {
		for _, v := range result.TelCell {
			telCell = append(telCell, utils.GetArabicNumbers(v))
		}
	}
	if len(result.TelWork) > 0 {
		for _, v := range result.TelWork {
			telCell = append(telCell, utils.GetArabicNumbers(v))
		}
	}
	result.TelCell = telCell

	if len(result.Company) == 0 && len(result.TelCell) == 0 {
		errMsg = "OCR识别失败"
	} else if len(result.Company) == 0 {
		// 获取图片识别客户名称的配置
		crmConfig, errCode := company.GetConfigDetailByCode("card_recognition_company_name")
		if errCode != nil {
			err = errCode
			return
		}
		if crmConfig.ConfigValue == "true" {
			errMsg = "名片中未识别到公司名称"
		}
	} else if len(result.TelCell) == 0 {
		// 获取图片识别手机号的配置
		crmConfig2, errCode := company.GetConfigDetailByCode("card_recognition_tel")
		if errCode != nil {
			err = errCode
			return
		}
		if crmConfig2.ConfigValue == "true" {
			errMsg = " 名片中未识别到手机号"
		}
	}

	logItem := new(cygx.AliyunOcrLog)
	logItem.ImgUrl = imageurl
	logItem.Result = string(body)
	logItem.CreateTime = time.Now()
	err = cygx.AddAliyunOcrLog(logItem)
	return
}