/**
* @Author: zou.yingbin
* @Create  : 2021/1/7 17:31
* @Modify  : 2021/1/7 17:31
 */

package models

import (
	"encoding/hex"
	"errors"
	"fmt"
	"mtp2_if/db"
	"mtp2_if/logger"
	"mtp2_if/utils"
	"strconv"
	"time"
)

// Hedgeoutmainconfig 外部母账号对冲配置表
// (要在系统参数表额外添加两个全局配置 1: 下单接口平台登录用户名[HedgePlateform_UserName] 2:下单接口平台登录密码[HedgePlateform_PWD])
type Hedgeoutmainconfig struct {
	Accountid                 int64  `json:"accountid"  xorm:"'ACCOUNTID'" binding:"required"`              // 资金账号ID(母账号)
	Channelid                 int64  `json:"channelid"  xorm:"'CHANNELID'"`                                 // 对冲渠道ID
	Marketid                  int64  `json:"marketid"  xorm:"'MARKETID'"`                                   // 内部市场ID(母账号的操作
	Hedgeaccountcode          string `json:"hedgeaccountcode"  xorm:"'HEDGEACCOUNTCODE'"`                   // 对冲账号ID
	Hedgeaccountpwd           string `json:"hedgeaccountpwd"  xorm:"-"`                                     // 对冲账号密码
	Channeladdress            string `json:"channeladdress"  xorm:"'CHANNELADDRESS'"`                       // 对冲渠道服务地址(多个地址用逗号分隔) -- 192.168.30.10:3000,192.168.30.10:3001
	Brokerid                  string `json:"brokerid"  xorm:"'BROKERID'"`                                   // 经纪公司代码
	Exchangeratecurrencygroup string `json:"exchangeratecurrencygroup"  xorm:"'EXCHANGERATECURRENCYGROUP'"` // 汇率币种组 [易盛]
	Accountcurrency           string `json:"accountcurrency"  xorm:"'ACCOUNTCURRENCY'"`                     // 资金账户基币 [易盛]
	Accountcurrecnygroup      string `json:"accountcurrecnygroup"  xorm:"'ACCOUNTCURRECNYGROUP'"`           // 资金账户币种组 [易盛]
	Authcode                  string `json:"authcode"  xorm:"'AUTHCODE'"`                                   // 授权码[易盛]
	Status                    int32  `json:"status"  xorm:"'STATUS'"`                                       // 渠道账号状态 1-可买入可卖出 2-可卖出不可买入
	Limitnumber               int64  `json:"limitnumber"  xorm:"'LIMITNUMBER'"`                             // 挂单笔数限额
	Appid                     string `json:"appid"  xorm:"-"`                                               // AppID
	Userproductinfo           string `json:"userproductinfo"  xorm:"'USERPRODUCTINFO'"`                     // 客户端产品信息
	Connectflag               int32  `json:"connectflag"  xorm:"'CONNECTFLAG'"`                             // 是否联接外部交易 - 0:不连接 1:连接
	Hedgeaccounttype          int32  `json:"hedgeaccounttype"  xorm:"'HEDGEACCOUNTTYPE'"`                   // 母账号类型 - 1-交易下单 2-跟单
	Fcid                      int32  `json:"fcid"  xorm:"'FCID'"`                                           // 期货公司ID

	Fcname string `json:"fcname" xorm:"FCNAME"` // 期货公司名称
}

// TableName is HEDGE_OUTMAINCONFIG
func (Hedgeoutmainconfig) TableName() string {
	return "HEDGE_OUTMAINCONFIG"
}

// GetOutAccountStatus 获取目标登录账号当前对冲账号在线状态
func (r *Hedgeoutmainconfig) GetOutAccountStatus(loginID int) ([]Hedgeoutmainconfig, error) {
	datas := make([]Hedgeoutmainconfig, 0)

	// 获取登录账号相关的所有资金账户
	taAccounts, err := GetTaAccountsByLoginID(loginID, 0)
	if err != nil {
		return nil, err
	}
	ids := make([]int, 0)
	for _, v := range taAccounts {
		// 母账户的Parentaccountid就是自己
		ids = append(ids, int(v.Parentaccountid))
	}
	if err := db.GetEngine().Table("HEDGE_OUTMAINCONFIG T").
		Select("T.*, F.FCNAME").
		Join("LEFT", "ERMCP_FUTURESCOMPANY F", "F.FCID = T.FCID").
		In("T.ACCOUNTID", ids).Find(&datas); err != nil {
		return nil, err
	}

	return datas, nil
}

// Hedgemarketopenlog 通道交易市场待开市日志表  - 市场的所有母账户与下单接口平台同步数据成功，市场才为待开市成功；
// 清空上一交易日数据
type Hedgemarketopenlog struct {
	Tradedate    string    `json:"tradedate"  xorm:"TRADEDATE"`                    // 交易日(yyyyMMdd)
	Accountid    int64     `json:"accountid"  xorm:"ACCOUNTID" binding:"required"` // 资金账号[外部母账户]
	Marketid     int64     `json:"marketid"  xorm:"MARKETID"`                      // 市场ID
	Status       int32     `json:"status"  xorm:"STATUS"`                          // 状态 - 1:待开市 2:开市 4:手工休市 5:闭市 10:日终处理开始 11:日终处理成功 12:日终处理失败
	Updatetime   time.Time `json:"updatetime"  xorm:"UPDATETIME"`                  // 更新时间
	Handlestatus int32     `json:"handlestatus"  xorm:"HANDLESTATUS"`              // 处理状态 - 1:登陆Mhp成功 2:登陆Mhp失败 3:登出Mhp

	Fcname string `json:"fcname" xorm:"-"` // 期货公司名称
}

// TableName is HEDGE_MARKETOPENLOG
func (Hedgemarketopenlog) TableName() string {
	return "HEDGE_MARKETOPENLOG"
}

// GetOutAccountStatus 获取目标登录账号当前对冲账号在线状态
func (r *Hedgemarketopenlog) GetOutAccountStatus(loginID int) ([]Hedgemarketopenlog, error) {
	datas := make([]Hedgemarketopenlog, 0)

	// 获取登录账号相关的所有资金账户
	taAccounts, err := GetTaAccountsByLoginID(loginID, 0)
	if err != nil {
		return nil, err
	}
	if len(taAccounts) == 0 {
		return nil, errors.New("无对应资金账户")
	}
	ids := make([]int, 0)
	ids_s := ""
	for _, v := range taAccounts {
		// 母账户的Parentaccountid就是自己
		ids = append(ids, int(v.Parentaccountid))
		ids_s += "," + strconv.Itoa(int(v.Parentaccountid))
	}
	ids_s = ids_s[1:]

	// 获取通道交易市场（目前只获取tradeMode = 15的第一个市场）
	marketRuns, err := GetMarketRunsByTradeMode(15)
	if err != nil {
		return nil, err
	}
	if len(marketRuns) == 0 {
		return nil, errors.New("无对应市场运行状态")
	}
	marketID := marketRuns[0].Marketid
	tradeDate := marketRuns[0].Tradedate

	if err := db.GetEngine().Table("TAACCOUNT T").Select("T.ACCOUNTID, H.TRADEDATE, H.MARKETID, H.STATUS, H.UPDATETIME, H.HANDLESTATUS").
		Join("LEFT", "HEDGE_MARKETOPENLOG H", fmt.Sprintf(`H.ACCOUNTID = T.ACCOUNTID 
															and H.ACCOUNTID in (%s) 
															and H.MARKETID = %d 
															and H.TRADEDATE = '%s'`, ids_s, marketID, tradeDate)).
		In("T.ACCOUNTID", ids).
		Find(&datas); err != nil {
		return nil, err
	}
	for i := range datas {
		hedgemarketopenlog := &datas[i]

		// 获取期货公司名称
		fcnames := make([]string, 0)
		if err := db.GetEngine().Table("ERMCP_FUTURESCOMPANY F").Select("F.FCNAME").
			Join("INNER", "HEDGE_OUTMAINCONFIG H", "H.FCID = F.FCID").
			Where("H.ACCOUNTID = ?", hedgemarketopenlog.Accountid).
			And("H.MARKETID = ?", marketID).Find(&fcnames); err != nil {
			return nil, err
		}
		if len(fcnames) > 0 {
			hedgemarketopenlog.Fcname = fcnames[0]
		}
	}

	return datas, nil
}

// ErmcpUserModel 客户资料结构
type ErmcpUserModel struct {
	USERID            int    `json:"userid"  xorm:"'USERID'"`                       // 用户ID
	MEMBERUSERID      int    `json:"memberuserid"  xorm:"'MEMBERUSERID'"`           // 所属机构ID
	USERINFOTYPE      string `json:"userinfotype"  xorm:"'USERINFOTYPE'"`           // 客户类型
	CUSTOMERNAME      string `json:"customername"  xorm:"'CUSTOMERNAME'"`           // 企业名称
	CARDTYPE          int32  `json:"cardtype"  xorm:"'CARDTYPE'"`                   // 证件类型
	CARDTYPENAME      string `json:"cardtypename"  xorm:"'CARDTYPENAME'"`           // 证件类型名称
	CARDNUM           string `json:"cardnum"  xorm:"'CARDNUM'"`                     // 证件号码
	MOBILE            string `json:"mobile"  xorm:"'MOBILE'"`                       // 手机号码
	TELPHONE          string `json:"telphone"  xorm:"'TELPHONE'"`                   // 联系电话
	ADDRESS           string `json:"address"  xorm:"'ADDRESS'"`                     // 通讯地址
	REMARK            string `json:"remark"  xorm:"'REMARK'"`                       // 备注
	STATUS            int32  `json:"status"  xorm:"'STATUS'"`                       // 账户状态 -  1:待激活 2:待审核 3:待复审 4:正常 5:审核拒绝 6:注销
	STATUSDESC        string `json:"statusdesc"`                                    // 账户状态中文描述
	ATTACHMENT1       string `json:"attachment1"  xorm:"'ATTACHMENT1'"`             // 附件1
	CARDFRONTPHOTOURL string `json:"cardfrontphotourl"  xorm:"'CARDFRONTPHOTOURL'"` // 证件正面图片地址
	CARDBACKPHOTOURL  string `json:"cardbackphotourl"  xorm:"'CARDBACKPHOTOURL'"`   // 证件反面图片地址
	COUNTRYID         int32  `json:"countryid"  xorm:"'COUNTRYID'"`                 // 国家
	PROVINCEID        int32  `json:"provinceid"  xorm:"'PROVINCEID'"`               // 省
	CITYID            int32  `json:"cityid"  xorm:"'CITYID'"`                       // 市
	DISTRICTID        int32  `json:"districtid"  xorm:"'DISTRICTID'"`               // 区域
	CREATETIME        string `json:"createtime"  xorm:"'CREATETIME'"`               // 创建时间
	MODIFYTIME        string `json:"modifytime"  xorm:"'MODIFYTIME'"`               // 修改时间
	AUDITTIME         string `json:"audittime"  xorm:"'AUDITTIME'"`                 // 审核时间
	NICKNAME          string `json:"nickname"  xorm:"'NICKNAME'"`                   // 昵称
	TAXPAYERNUM       string `json:"taxpayernum"  xorm:"'taxpayernum'"`             // 纳税人识别号
	LEGALPERSONNAME   string `json:"legalpersonname"  xorm:"'legalpersonname'"`     // 法人姓名(企业)
	CONTACTNAME       string `json:"contactname"  xorm:"'contactname'"`             // 联系人
	EMAIL             string `json:"email"  xorm:"'EMAIL'"`                         // 邮件
}

func (r *ErmcpUserModel) buildWskhSql(accStatus string) string {
	str := "select t.userid," +
		"       t.memberareaid      MEMBERUSERID," +
		"       t.USERINFOTYPE," +
		"       t.CUSTOMERNAME," +
		"       t.NICKNAME," +
		"       t.CARDTYPE," +
		"       e.enumdicname       CARDTYPENAME," +
		"       t.CARDNUM," +
		"       t.mobilephone       MOBILE," +
		"       t.TELPHONE," +
		"       t.cardaddress       ADDRESS," +
		"       t.REMARK," +
		"       t.ATTACHMENT1," +
		"       t.CARDFRONTPHOTOURL," +
		"       t.CARDBACKPHOTOURL," +
		"       t.userstate         status," +
		"       t.countryid," +
		"       t.provinceid," +
		"       t.districtid," +
		"       to_char(t.createtime,'yyyy-mm-dd hh24:mi:ss') createtime," +
		"       t.cityid," +
		"       to_char(t.modifiedtime,'yyyy-mm-dd hh24:mi:ss') modifytime," +
		"       to_char(t.auditime,'yyyy-mm-dd hh24:mi:ss') audittime," +
		"       t.taxpayernum," +
		"       t.legalpersonname," +
		"       t.contactname," +
		"       t.email" +
		"  from wskh_userinfo t" +
		"  left join enumdicitem e" +
		"    on t.cardtype = e.enumitemname" +
		"   and e.enumdiccode = 'certificatetype'" +
		" where t.userstate in (%v)" +
		"   and t.usertype = 6" +
		"   and t.memberareaid = %v" +
		" order by t.modifiedtime desc"
	return fmt.Sprintf(str, accStatus, r.MEMBERUSERID)
}

func (r *ErmcpUserModel) buildSql(accStatus string) string {
	str := "select t.userid," +
		"       t.memberuserid," +
		"       u.USERINFOTYPE," +
		"       u.CUSTOMERNAME," +
		"       u.NICKNAME," +
		"       u.CARDTYPEID        CARDTYPE," +
		"       e.enumdicname       CARDTYPENAME," +
		"       u.CARDNUM," +
		"       u.MOBILE," +
		"       u.TELPHONE," +
		"       u.ADDRESS," +
		"       u.REMARK," +
		"       u.ATTACHMENT1," +
		"       u.CARDFRONTPHOTOURL," +
		"       u.CARDBACKPHOTOURL," +
		"       t.accountstatus     status," +
		"       u.countryid," +
		"       u.provinceid," +
		"       u.districtid," +
		"       u.taxpayernum," +
		"       u.legalpersonname," +
		"       u.contactname," +
		"       u.email," +
		"       to_char(t.createtime,'yyyy-mm-dd hh24:mi:ss') createtime," +
		"       to_char(t.modifytime,'yyyy-mm-dd hh24:mi:ss') modifytime," +
		"       to_char(t.audittime,'yyyy-mm-dd hh24:mi:ss') audittime," +
		"       u.cityid" +
		"  from useraccount t" +
		"  left join userinfo u" +
		"    on t.userid = u.userid" +
		"  left join enumdicitem e" +
		"    on u.cardtypeid = e.enumitemname" +
		"   and e.enumdiccode = 'certificatetype'" +
		" where t.usertype = 6" +
		"   and t.accountstatus in (%v)" +
		"   and t.memberuserid = %v"
	// 查正常状态,按审核时间排序
	if accStatus == "4" {
		str += " order by t.audittime desc"
	} else if accStatus == "6" {
		// 停用状态按修改时间排序
		str += " order by t.modifytime desc"
	}

	return fmt.Sprintf(str, accStatus, r.MEMBERUSERID)
}

// DecryptField 解密卡号和电话号码字段
func (r *ErmcpUserModel) DecryptField(isWskh bool) {
	key := "0d299ce2d4105282f7471074cb0f9f9d"
	key2, _ := hex.DecodeString(key)
	fd := func(str string) string {
		if str == "" {
			return str
		}
		d, _ := hex.DecodeString(str)
		if dst, err := utils.AESDecrypt(d, key2); err == nil {
			return string(dst)
		}
		return str
	}

	r.CARDNUM = fd(r.CARDNUM)
	r.MOBILE = fd(r.MOBILE)
	r.EMAIL = fd(r.EMAIL)

	if !isWskh {
		// 正式用户表(非网上开户)需要解密电话号码
		r.TELPHONE = fd(r.TELPHONE)
	}

	if isWskh && len(r.ADDRESS) != 0 { // 地址不为空
		r.ADDRESS = fd(r.ADDRESS)
	}
}

// DecodeStausName 账户状态名称
func (r *ErmcpUserModel) DecodeStausName(queryType int32) {
	if queryType == 1 || queryType == 2 {
		// 网上开户状态
		if r.STATUS == 1 {
			r.STATUSDESC = "未提交"
		} else if r.STATUS == 2 || r.STATUS == 4 {
			r.STATUSDESC = "待审核"
		} else if r.STATUS == 3 || r.STATUS == 5 {
			r.STATUSDESC = "审核拒绝"
		}
	} else if queryType == 3 || queryType == 4 {
		if r.STATUS == 4 {
			r.STATUSDESC = "正常"
		} else if r.STATUS == 6 {
			r.STATUSDESC = "已注销"
		}
	}
}

// GetData 查询客户资料
func (r *ErmcpUserModel) GetData(queryType int32) ([]ErmcpUserModel, error) {
	sData := make([]ErmcpUserModel, 0)
	e := db.GetEngine()
	var sqlId string
	var isWskh bool = false
	switch queryType {
	case 1: //未提交
		sqlId = r.buildWskhSql("1")
		isWskh = true
	case 2: //待审核
		sqlId = r.buildWskhSql("2,4,5")
		isWskh = true
	case 3: //正常
		sqlId = r.buildSql("4")
	case 4: //已停用
		sqlId = r.buildSql("6")
	}
	s := e.SQL(sqlId)
	if err := s.Find(&sData); err != nil {
		logger.GetLogger().Errorf("ermcp query fail:%v", err)
		return sData, err
	}

	// 解密
	for i := range sData {
		sData[i].DecryptField(isWskh)
		sData[i].DecodeStausName(queryType)
	}

	return sData, nil
}
