// JSON TYPE
type JSONPrimitive = string | number | boolean | null
type JSONArray = Array<JSONValue>
type JSONValue = JSONPrimitive | JSONObject | JSONArray
type JSONObject = {[member: string]: JSONValue}

export interface SDK {
  getToken: (holderName?: string) => Promise<any>
}

export interface PublicKey {
  key: string // 初始化代币
  expand?: Expand
}

export interface InitialData extends PaypalSPBData, OceanpayData, EbanxData {
  env: 'prod' | 'dev' // 当前环境 用于个别SDK加载脚本环境区分
  sdkName: '2checkout' | 'ebanx' | 'checkout' | 'oceanPay' | 'paypalSPB' | 'asiaBill' // sdk名
  domId: string // 需要渲染的dom id
  layoutType?: 0 // 布局类型
  styleOption?: StyleOption
  language?: string // 语言 没传根据sdk按照sdk本身的默认locale
  country?: string // 国家码 没传根据sdk按照sdk本身的默认country
  label?: Label // label提示
  placeholder?: Placeholder // input框提示
  errorTips?: ErrorTips // 表单错误提示
  btnText?: string // 按钮文本
  fieldData?: FieldData // 表单默认数据
  createToken?: (response: any) => void // 点击按钮获取token回调
  fieldOnChange?: (fieldParams: FieldParams) => void // 表单填写信息时回调
  fieldOnBlur?: (fieldParams: FieldParams) => void // 表单输入框失焦时回调
  fieldComplete?: (fieldCompleteParams: FieldCompleteParams) => void // 表单填写完成时回调
  reportSDKLoading?: (reportSDKLoadingParams: ReportSDKLoadingParams) => void // SDK脚本加载时间
  // todo 暴露各个表单事件
}

export interface OceanpayData {
  rewriteCssUrl?: string // oceanPay css重写地址  必须https
}
export interface PaypalSPBData {
  createOrder?: (response: any) => Promise<string> // paypalSPB选择按钮时的回调
}

export interface EbanxData {
  isDebitCard?: boolean // 是否借记卡，ebanx借记卡和信用卡提交处理方式不同
}

export interface Expand {
  currency?: string
}

export interface StyleOption {
  commonStyle?: CommonStyle // 传给sdk的style实例对象，不是css对象
  componentStyle?: ComponentStyle
}

export interface CommonStyle extends JSONObject {
  paypalSPBStyle?: {
    layout?: 'vertical' | 'horizontal'
    color?: 'gold' | 'blue' | 'silver' | 'white' | 'black'
    shape?: 'rect' | 'pill'
    label?: 'paypal' | 'checkout' | 'buynow' | 'pay' | 'installment'
    height?: number // set the style.height option to a value from 25 to 55.
    tagline?: boolean
  }
}

export interface ComponentStyle {
  formStyle?: JSONObject
  nameInputStyle?: InputStyle
  cardInputStyle?: InputStyle
  expirationInputStyle?: InputStyle
  cvvInputStyle?: InputStyle
  btnStyle?: {
    normalBackground: string // 正常按钮颜色
    disableBackground: string // 禁用按钮颜色
  } & JSONObject
}

export interface InputStyle {
  labelStyle?: JSONObject
  inputWrapperStyle?: JSONObject
  inputStyle?: JSONObject
  messageStyle?: JSONObject
}

export interface Label {
  userNameLabel?: string
  cardNumberLabel?: string
  expirationLabel?: string
  cvvLabel?: string
}

export interface Placeholder {
  userNamePlaceholder?: string
  cardNumberPlaceholder?: string
  expiryMonthPlaceholder?: string
  expiryYearPlaceholder?: string
  cvvPlaceholder?: string
}

export interface ErrorTips {
  userNameErrorTips?: string
  cardNumberErrorTips?: string
  expirationErrorTips?: string
  cvvErrorTips?: string
}

export interface FieldParams {
  message?: string
  param?: 'username' | 'cardnumber' | 'expiration' | 'cvv'
}

export interface BinLookUpResponse {
  number: JSONObject
  scheme: string
  country: {
    numeric: string
    alpha2: string
    name: string
    emoji: string
    currency: string
    latitude: number
    longitude: number
  }
  bank: {
    name: string
    url: string
    phone: string
  }
}

export interface ReportSDKLoadingParams {
  time?: number
}

export interface FieldCompleteParams {
  userName?: string
  cardNumber?: string
  expiration?: string
  cvv?: string
}

export interface FieldData extends AsiabillFieldData, EbanxFieldData {
  userName?: string // 2checkout ebanx使用
}

export interface AsiabillFieldData {
  merNo?: string //	【商户号】
  gatewayNo?: string //【网关接入号】
  orderNo?: string //【商户订单号】 在该订单号是成功/待处理/待确认的状态下,不允许再次抛送此订单号。
  orderCurrency?: string //【交易币种】详见【附录】交易币种(ISO 4217)https://www.asiabill.com/developers/347-cn.html#currency
  orderAmount?: string //【交易金额】应为小数点后2位小数。
  firstName?: string //【客人的名】 长度必须在2-100之间。否则不能交易。
  lastName?: string //【客人的姓】 长度必须在2-50之间。否则不能交易。
  email?: string //【客人的邮件】 长度必须在2-200之间。否则不能交易。
  phone?: string //	【客人的联系电话】 长度必须在2-50之间。否则不能交易。
  paymentMethod?: string //【支付方式】 支付方式代码请参考具体支付接口
  shipFirstName?: string //【收件人的名】
  shipLastName?: string //【收件人的姓】
  shipPhone?: string //【收件人的联系电话】
  shipCountry?: string //【收件人的国家】
  shipState?: string //【收件人的州】
  shipCity?: string //【收件人的城市】
  shipAddress?: string //【收件人的地址】
  shipZip?: string //【收件人的邮编】
  returnUrl?: string //【交易返回地址】Asiabill处理完请求后，自动跳转到请求参数中的returnUrl地址。
  callbackUrl?: string //【后台通知地址】当传了此值则异步通知使用该URL通知
  remark?: string //【备注】可作为扩展信息，提交什么就返回什么。
}

export interface EbanxFieldData {
  userName?: string // 用户名称  对用用户表单userName
  orderAmount?: string //【交易金额】应为小数点后2位小数。  对应下单币种
  orderCurrency?: string //【交易币种】
  shipAddress?: string //【收件人的地址】  对用用户表单address
  shipCountry?: string //【收件人的国家】
  shipState?: string //【收件人的州】  对用用户表单state
  shipCity?: string //【收件人的城市】  对用用户表单city
  shipZip?: string //【收件人的邮编】  对用用户表单zipcode
  email?: string //【客人的邮件】  对用用户表单email
  shipPhone?: string //【收件人的联系电话】  对用用户表单phoneNumber
  homePhone?: string //【家庭电话】
  CPF?: string // 【CPF，巴西身份证】  对用用户表单document
}

// eslint-disable-next-line prettier/prettier
declare module "@efox/pay" {
  export default class PAYSDK {
    constructor(publicKey?: PublicKey, initialData: InitialData)
    checkKey(publicKey: PublicKey): boolean
    getToken(holderName: string): Promise<any>
  }
}
