package hostwithdrawal

import (
	"errors"
	"strings"
)

const (
	recordTypeSalaryTransfer = "salary_transfer"
	recordTypeWithdrawal     = "withdrawal"

	statusCompleted = "completed"
	statusPending   = "pending"
	statusApproved  = "approved"
	statusRejected  = "rejected"

	assetCoinSellerCoin  = "COIN_SELLER_COIN"
	bizSalaryTransfer    = "salary_transfer_to_coin_seller"
	transactionSucceeded = "succeeded"

	assetHostSalary   = "HOST_SALARY_USD"
	assetAgencySalary = "AGENCY_SALARY_USD"
	assetBDSalary     = "BD_SALARY_USD"
	assetAdminSalary  = "ADMIN_SALARY_USD"
)

var errInvalidArgument = errors.New("invalid argument")

type listQuery struct {
	Page            int
	PageSize        int
	AppCode         string
	RecordType      string
	Identity        string
	SalaryAssetType string
	Status          string
	Keyword         string
	StartAtMS       int64
	EndAtMS         int64
}

func normalizeListQuery(query listQuery) (listQuery, error) {
	if query.Page < 1 {
		query.Page = 1
	}
	if query.PageSize < 1 {
		query.PageSize = 20
	}
	if query.PageSize > 100 {
		query.PageSize = 100
	}
	query.AppCode = strings.ToLower(strings.TrimSpace(query.AppCode))
	query.RecordType = strings.TrimSpace(query.RecordType)
	query.Identity = strings.TrimSpace(query.Identity)
	query.Status = strings.TrimSpace(query.Status)
	query.Keyword = strings.TrimSpace(query.Keyword)
	if query.StartAtMS > 0 && query.EndAtMS > 0 && query.StartAtMS >= query.EndAtMS {
		return listQuery{}, errInvalidArgument
	}

	switch strings.ToLower(query.RecordType) {
	case "", "all":
		query.RecordType = ""
	case recordTypeSalaryTransfer:
		query.RecordType = recordTypeSalaryTransfer
	case recordTypeWithdrawal:
		query.RecordType = recordTypeWithdrawal
	default:
		return listQuery{}, errInvalidArgument
	}

	salaryAssetType, identity, err := normalizeIdentity(query.Identity)
	if err != nil {
		return listQuery{}, err
	}
	query.SalaryAssetType = salaryAssetType
	query.Identity = identity

	switch strings.ToLower(query.Status) {
	case "", "all":
		query.Status = ""
	case statusCompleted:
		query.Status = statusCompleted
	case statusPending:
		query.Status = statusPending
	case statusApproved:
		query.Status = statusApproved
	case statusRejected:
		query.Status = statusRejected
	default:
		return listQuery{}, errInvalidArgument
	}
	return query, nil
}

func normalizeIdentity(value string) (string, string, error) {
	switch strings.ToUpper(strings.TrimSpace(value)) {
	case "", "ALL":
		return "", "", nil
	case "HOST", assetHostSalary:
		return assetHostSalary, "host", nil
	case "AGENCY", assetAgencySalary:
		return assetAgencySalary, "agency", nil
	case "BD", assetBDSalary:
		return assetBDSalary, "bd", nil
	case "ADMIN", "BD_LEADER", "BD_LEADER_ADMIN", assetAdminSalary:
		return assetAdminSalary, "bd_leader_admin", nil
	default:
		return "", "", errInvalidArgument
	}
}

func identityFromAsset(assetType string) string {
	_, identity, err := normalizeIdentity(assetType)
	if err != nil {
		return ""
	}
	return identity
}
