package utils

import (
	"context"
	"crypto/rsa"
	"database/sql"
	_ "github.com/go-sql-driver/mysql"
	"github.com/gorilla/websocket"
	"github.com/redis/go-redis/v9"
	"github.com/wechatpay-apiv3/wechatpay-go/core/notify"
	"github.com/wechatpay-apiv3/wechatpay-go/services/payments/native"
	"log"
	"sync"
)

const (
	HttpOk       = 200
	HttpAuthFail = 403
	HttpNotFound = 404
	HttpError    = 500

	FullPatten      = "QWERTYUIOPLKJHGFDSAZXCVBNM0123456789zxcvbnmlkjhgfdsaqwertyuiop-_"
	NumberPatten    = "0123456789"
	AlphaPatten     = "QWERTYUIOPLKJHGFDSAZXCVBNMzxcvbnmlkjhgfdsaqwertyuiop"
	AlphaNumPatten  = "QWERTYUIOPLKJHGFDSAZXCVBNM0123456789zxcvbnmlkjhgfdsaqwertyuiop"
	UppercasePatten = "QWERTYUIOPLKJHGFDSAZXCVBNM"
	LowercasePatten = "zxcvbnmlkjhgfdsaqwertyuiop"

	RedisNil = redis.Nil
)

type WsMsg struct {
	Event string `json:"event"`
	Data  any    `json:"data"`
}

type Response struct {
	Status bool   `json:"status"`
	Msg    string `json:"msg"`
	Data   any    `json:"data"`
}

type JsonType = map[string]any

type Config struct {
	Release      bool   `json:"release"`
	ServerAddr   string `json:"server_addr"`
	ServerPrefix string `json:"server_prefix"`
	TimeFormat   string `json:"time_format"`

	MysqlHost     string `json:"mysql_host"`
	MysqlPort     int    `json:"mysql_port"`
	MysqlUser     string `json:"mysql_user"`
	MysqlPass     string `json:"mysql_pass"`
	MysqlDatabase string `json:"mysql_database"`

	RedisHost     string `json:"redis_host"`
	RedisPort     int    `json:"redis_port"`
	RedisPass     string `json:"redis_pass"`
	RedisDatabase int    `json:"redis_database"`

	WxPayTitle    string `json:"wx_pay_title"`
	WxMerchantAcc string `json:"wx_merchant_acc"`
	WxAppId       string `json:"wx_app_id"`
	WxApiCertSeq  string `json:"wx_api_cert_seq"`
	WxApiCertPath string `json:"wx_api_cert_path"`
	WxApiV3Key    string `json:"wx_api_v3_key"`

	ServerPrivate string `json:"server_private"`
	ServerPublic  string `json:"server_public"`
	ClientPrivate string `json:"client_private"`
	ClientPublic  string `json:"client_public"`
}

var ServerPrefix string
var Logger *log.Logger

// database
var (
	Redis *redis.Client
	Mysql *sql.DB
)

// de-encrypt, SerPri->CliPub, CliPri->SerPub
var (
	ClientPri string
	ClientPub string
	ServerPri *rsa.PrivateKey
	ServerPub *rsa.PublicKey
)

// wechat pay
var (
	WxAppId string
	WxMchId string
	WxV3Key string
	WxTitle string

	WxCertSeq    string
	WxCertPath   string
	WxPrivateKey *rsa.PrivateKey

	WxPaySrv native.NativeApiService
	WxPayCli context.Context
	WxCrtHdr *notify.Handler
)

type SellerDevice struct {
	Online bool
	Conn   *websocket.Conn
}

// websocket
var (
	UpgradeHttp2Ws = websocket.Upgrader{
		ReadBufferSize:  1024,
		WriteBufferSize: 1024,
		CheckOrigin:     CheckOrigin,
	}
	SellerDevices = make(map[string]*SellerDevice)
	SellerLock    sync.Mutex
	ManagerWss    = make(map[string]*websocket.Conn)
	ManagerLock   sync.Mutex
	WorkerWss     = make(map[string]*websocket.Conn)
	WorkerLock    sync.Mutex
	DebugWss      = make(map[string]*websocket.Conn)
	DebugLock     sync.Mutex
)
