package ng_cws_client

import (
	"encoding/json"
	"errors"
	"git.sxidc.com/service-supports/cws-sdk/service"
	"git.sxidc.com/service-supports/cws-sdk/service/request"
	"git.sxidc.com/service-supports/cws-sdk/service/response"
	"git.sxidc.com/service-supports/cws-sdk/utils"
	"git.sxidc.com/service-supports/cws-sdk/utils/http_client"
	"time"
)

var NGCwsClient *http_client.Client
var cwsUrl string
var cwsTimeOut time.Duration

func Init(url string, timeout time.Duration) error {
	if utils.IsStringEmpty(url) {
		return errors.New("未配置CWS地址")
	}

	NGCwsClient = http_client.New()
	cwsTimeOut = timeout
	cwsUrl = url
	return nil
}

func Destroy() {
	http_client.Destroy(NGCwsClient)
}

func StartWorkFlowByBusinessType(reqParams *request.StartWorkFlowByBusinessTypeRequest) (string, error) {
	//根据业务类型获取流程模型ID
	workflowTemplateId, err := getWorkTemplateInfoByBusinessType(reqParams.BusinessType, reqParams.TenantID)
	if err != nil {
		return "", err
	}
	if utils.IsStringEmpty(workflowTemplateId) {
		return "", errors.New("该业务类型未配置流程")
	}

	//发起流程前校验 获取人员组织信息
	customStructureInfo, err := LaunchWorkflowPrepare(&request.LaunchWorkflowPrepareParams{
		WorkflowTemplateID: workflowTemplateId,
		CreateUserID:       reqParams.CreateUserID,
		TenantID:           reqParams.TenantID,
	})
	if err != nil {
		return "", err
	}

	////发起流程
	//businessObject := &request.WorkflowBusinessObject{
	//	BusinessType:   reqParams.BusinessType,
	//	BusinessObject: reqParams.Data,
	//}
	jsonBytes, err := json.Marshal(reqParams.Data)
	if err != nil {
		return "", err
	}
	businessObjectStr := string(jsonBytes)

	workflowId, err := StartWorkflow(&request.StartWorkflowRequest{
		WorkflowTemplateID: workflowTemplateId,
		LaunchUserName:     reqParams.LaunchUserName,
		Matter:             reqParams.Matter,
		BusinessObject:     businessObjectStr,
		UserStructureID:    customStructureInfo.ID,
		CreateUserID:       reqParams.CreateUserID,
		TenantID:           reqParams.TenantID,
	})
	if err != nil {
		return "", err
	}

	return workflowId, nil

}

func StartWorkflow(reqParams *request.StartWorkflowRequest) (string, error) {
	if utils.IsStringEmpty(cwsUrl) {
		return "", errors.New("未配置CWS地址")
	}
	requestJson, err := json.Marshal(reqParams)
	if err != nil {
		return "", err
	}
	postResponse, err := NGCwsClient.NewRequest(http_client.WithNewRequestTimeout(cwsTimeOut)).
		Post(cwsUrl+service.StartWorkFlowMethodName, requestJson)
	if err != nil {
		return "", err
	}

	resp := new(response.InfoResponse[string])
	err = postResponse.Json(resp)
	if err != nil {
		return "", err
	}
	if !resp.Success {
		return "", errors.New(resp.Msg)
	}

	return resp.Info, nil
}

func getWorkTemplateInfoByBusinessType(businessType string, tenantId string) (string, error) {

	//查询业务类型配置
	queryParams := map[string]string{
		"code":     businessType,
		"tenantId": tenantId,
	}
	newRequest := NGCwsClient.NewRequest(http_client.WithNewRequestTimeout(cwsTimeOut))
	newRequest.SetQueryParams(queryParams)
	resp, err := newRequest.Get(cwsUrl + service.GetWorkTemplateByCodeMethodName)
	if err != nil {
		return "", err
	}
	respInfo := new(response.InfoResponse[response.BusinessCatalogsInfoWithWorkflowTemplate])
	err = resp.Json(respInfo)
	if err != nil {
		return "", err
	}
	if !respInfo.Success {
		return "", errors.New(respInfo.Msg)
	}
	return respInfo.Info.WorkTemplateId, nil
}

func LaunchWorkflowPrepare(reqParams *request.LaunchWorkflowPrepareParams) (*response.CustomStructureInfo, error) {

	requestJson, err := json.Marshal(reqParams)
	if err != nil {
		return nil, err
	}
	postResponse, err := NGCwsClient.NewRequest(http_client.WithNewRequestTimeout(cwsTimeOut)).
		Post(cwsUrl+service.StartWorkFlowPrepareMethodName, requestJson)
	if err != nil {
		return nil, err
	}

	resp := new(response.InfosResponse[response.PrepareInfo])
	err = postResponse.Json(resp)
	if err != nil {
		return nil, err
	}
	if !resp.Success {
		return nil, errors.New(resp.Msg)
	}
	customStructureInfo := &response.CustomStructureInfo{}
	for _, info := range resp.Infos {
		if info.ID == "userStructureId" {
			customStructureInfo.ID = info.Options[0].Value
			break
		}
	}

	return customStructureInfo, nil
}