package taaccount

import (
	"fmt"
	"mtp2_if/db"
	"mtp2_if/global/app"
	"mtp2_if/global/e"
	"mtp2_if/logger"
	"mtp2_if/models"
	"net/http"

	"github.com/gin-gonic/gin"
)

// GetTaAccountsReq 获取资金账户请求参数
type GetTaAccountsReq struct {
	LoginID       int `form:"loginID" binding:"required"`
	TaAccountType int `form:"taAccountType"`
}

// GetTaAccounts 获取资金账户信息
// @Summary 获取资金账户信息
// @Produce json
// @Security ApiKeyAuth
// @Param loginID query int true "登录账户"
// @Param taAccountType query int false "账号类型 - 1:外部账号 2:内部账号 3:内部做市自营账号 4:内部做市接单账号"
// @Success 200 {object} models.Taaccount
// @Failure 500 {object} app.Response
// @Router /TaAccount/GetTaAccounts [get]
// @Tags 资金账户
func GetTaAccounts(c *gin.Context) {
	appG := app.Gin{C: c}

	// 获取请求参数
	var req GetTaAccountsReq
	if err := appG.C.ShouldBindQuery(&req); err != nil {
		logger.GetLogger().Errorf("GetTaAccounts failed: %s", err.Error())
		appG.Response(http.StatusBadRequest, e.INVALID_PARAMS, nil)
		return
	}

	// 查询数据
	taAccounts, err := models.GetTaAccountsByLoginID(req.LoginID, req.TaAccountType)
	if err != nil {
		// 查询失败
		logger.GetLogger().Errorf("GetTaAccounts failed: %s", err.Error())
		appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil)
		return
	}

	// 如果是母账户，要从对冲外部资金账户表获取资金信息
	for i, _ := range taAccounts {
		item := &taAccounts[i]
		if item.Ismain == 1 {
			hedgeOutTaAccount, _ := models.GetHedgeOutTaAccount(int(item.Accountid))
			if hedgeOutTaAccount != nil {
				item.Balance = hedgeOutTaAccount.Prebalance
				item.Currentbalance = hedgeOutTaAccount.Balance
				item.Usedmargin = hedgeOutTaAccount.Usedmargin
				item.Freezemargin = hedgeOutTaAccount.Freezemargin
				item.Freezecharge = hedgeOutTaAccount.Freezecharge
				item.Otherfreezemargin = hedgeOutTaAccount.Otherfreezemargin
				item.Inamount = hedgeOutTaAccount.Inamount
				item.Outamount = hedgeOutTaAccount.Outamount
				item.Paycharge = hedgeOutTaAccount.Paycharge
				item.Closepl = hedgeOutTaAccount.Closepl
			}
		}
	}

	// 查询成功
	logger.GetLogger().Debugln("GetTaAccounts successed: %v", taAccounts)
	appG.Response(http.StatusOK, e.SUCCESS, taAccounts)
}

// QueryAmountLogReq 资金流水查询（当前）请求参数
type QueryAmountLogReq struct {
	app.PageInfo
	AccountID   string `form:"accountID"`   // 资金账户
	OperateType string `form:"operateType"` // 资金操作类型
}

// QueryAmountLogRsp 资金流水查询（当前）返回模型
type QueryAmountLogRsp struct {
	models.Taaccountlog `xorm:"extends"`

	MarketName      string `json:"marketname"  xorm:"'MARKETNAME'"`        // 市场名称
	TradeMode       uint32 `json:"trademode"  xorm:"'TRADEMODE'"`          // 交易模式
	GoodsCode       string `json:"goodscode"  xorm:"'GOODSCODE'"`          // 商品代码
	GoodsName       string `json:"goodsname"  xorm:"'GOODSNAME'"`          // 商品名称
	AGoodsCode      string `json:"agoodscode"  xorm:"'AGOODSCODE'"`        // 竞拍商品代码
	AGoodsName      string `json:"agoodsname"  xorm:"'GOODSNAME'"`         // 竞拍商品名称
	DGoodsCode      string `json:"dgoodscode"  xorm:"'DGOODSCODE'"`        // 交割商品代码
	DGoodsName      string `json:"dgoodsname"  xorm:"'DGOODSNAME'"`        // 交割商品名称
	OperateTypeName string `json:"OPERATETYPENAME" xorm:"OPERATETYPENAME"` // 资金操作类型名称
}

// QueryAmountLog 资金流水查询（当前）
// @Summary 资金流水查询（当前）
// @Produce json
// @Security ApiKeyAuth
// @Param page query int false "页码"
// @Param pagesize query int false "每页条数"
// @Param accountID query string true "资金账户 - 格式：1,2,3"
// @Param OperateType query string false "资金操作类型 - 格式：1,2,3"
// @Success 200 {object} QueryAmountLogRsp
// @Failure 500 {object} app.Response
// @Router /TaAccount/QueryAmountLog [get]
// @Tags 资金账户
// 参考通用查询：QueryClientAmountLog
func QueryAmountLog(c *gin.Context) {
	appG := app.Gin{C: c}

	// 获取请求参数
	var req QueryAmountLogReq
	if err := appG.C.ShouldBindQuery(&req); err != nil {
		logger.GetLogger().Errorf("QueryAmountLog failed: %s", err.Error())
		appG.Response(http.StatusBadRequest, e.INVALID_PARAMS, nil)
		return
	}

	// 查询数据
	datas := make([]QueryAmountLogRsp, 0)
	engine := db.GetEngine()
	s := engine.Table("TAACCOUNTLOG").
		Join("INNER", "ENUMDICITEM", "ENUMDICITEM.ENUMITEMSTATUS = 1 and ENUMDICITEM.ENUMDICID = 39 and ENUMDICITEM.ENUMITEMNAME = TAACCOUNTLOG.OPERATETYPE").
		Join("LEFT", "MARKET", "MARKET.MARKETID = TAACCOUNTLOG.MARKETID").
		Join("LEFT", "GOODS", "GOODS.GOODSID = TAACCOUNTLOG.GOODSID").
		Join("LEFT", "AUCTION_ORDERINFO", "AUCTION_ORDERINFO.GOODSID = TAACCOUNTLOG.GOODSID").
		Join("LEFT", "DELIVERYGOODS", "DELIVERYGOODS.DELIVERYGOODSID = TAACCOUNTLOG.GOODSID").
		Select(`to_char(TAACCOUNTLOG.RELATIONORDERID) as RELATIONORDERID, TAACCOUNTLOG.*, 
				MARKET.MARKETNAME, MARKET.TRADEMODE, 
				GOODS.GOODSCODE, GOODS.GOODSNAME, 
				AUCTION_ORDERINFO.GOODSCODE AS AGOODSCODE, AUCTION_ORDERINFO.GOODSNAME AS AGOODSNAME, 
				DELIVERYGOODS.DELIVERYGOODSCODE AS DGOODSCODE, DELIVERYGOODS.DELIVERYGOODSNAME AS DGOODSNAME, 
				ENUMDICITEM.ENUMDICNAME AS OPERATETYPENAME`).
		Where(fmt.Sprintf("TAACCOUNTLOG.ACCOUNTID in (%s)", req.AccountID)).Desc("TAACCOUNTLOG.AUTOID")
	if len(req.OperateType) > 0 {
		s = s.And(fmt.Sprintf("TAACCOUNTLOG.OPERATETYPE in (%s)", req.OperateType))
	}
	if err := s.Find(&datas); err != nil {
		// 查询失败
		logger.GetLogger().Errorf("QueryAmountLog failed: %s", err.Error())
		appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil)
		return
	}

	// 查询成功返回
	if req.PageSize > 0 {
		// 分页
		rst := make([]QueryAmountLogRsp, 0)
		// 开始上标
		start := req.Page * req.PageSize
		// 结束下标
		end := start + req.PageSize

		if start <= len(datas) {
			// 判断结束下标是否越界
			if end > len(datas) {
				end = len(datas)
			}
			rst = datas[start:end]
		} else {
			rst = datas[0:0]
		}

		logger.GetLogger().Debugln("QueryAmountLog successed: %v", rst)
		appG.ResponseByPage(http.StatusOK, e.SUCCESS, rst, app.PageInfo{Page: req.Page, PageSize: req.PageSize, Total: len(datas)})
	} else {
		// 不分页
		logger.GetLogger().Debugln("QueryAmountLog successed: %v", datas)
		appG.Response(http.StatusOK, e.SUCCESS, datas)
	}
}

// QueryHisAmountLogReq 资金流水查询（历史）请求参数
type QueryHisAmountLogReq struct {
	app.PageInfo
	AccountID   string `form:"accountID"`   // 资金账户
	OperateType string `form:"operateType"` // 资金操作类型
	StartDate   string `form:"startDate"`   // 开始时间
	EndDate     string `form:"endDate"`     // 结束时间
}

// QueryHisAmountLogRsp 资金流水查询（历史）返回模型
type QueryHisAmountLogRsp struct {
	models.Histaaccountlog `xorm:"extends"`

	MarketName      string `json:"marketname"  xorm:"'MARKETNAME'"`        // 市场名称
	TradeMode       uint32 `json:"trademode"  xorm:"'TRADEMODE'"`          // 交易模式
	GoodsCode       string `json:"goodscode"  xorm:"'GOODSCODE'"`          // 商品代码
	GoodsName       string `json:"goodsname"  xorm:"'GOODSNAME'"`          // 商品名称
	AGoodsCode      string `json:"agoodscode"  xorm:"'AGOODSCODE'"`        // 竞拍商品代码
	AGoodsName      string `json:"agoodsname"  xorm:"'GOODSNAME'"`         // 竞拍商品名称
	DGoodsCode      string `json:"dgoodscode"  xorm:"'DGOODSCODE'"`        // 交割商品代码
	DGoodsName      string `json:"dgoodsname"  xorm:"'DGOODSNAME'"`        // 交割商品名称
	OperateTypeName string `json:"OPERATETYPENAME" xorm:"OPERATETYPENAME"` // 资金操作类型名称
}

// QueryHisAmountLog 资金流水查询（历史）
// @Summary 资金流水查询（历史）
// @Produce json
// @Security ApiKeyAuth
// @Param page query int false "页码"
// @Param pagesize query int false "每页条数"
// @Param accountID query string true "资金账户 - 格式：1,2,3"
// @Param OperateType query string false "资金操作类型 - 格式：1,2,3"
// @Param startDate query string false "开始时间 - 闭区间，格式：yyyy-MM-dd"
// @Param endDate query string false "结束时间 - 闭区间，格式：yyyy-MM-dd"
// @Success 200 {object} QueryHisAmountLogRsp
// @Failure 500 {object} app.Response
// @Router /TaAccount/QueryHisAmountLog [get]
// @Tags 资金账户
// 参考通用查询：Client_QueryHis_taaccountlog
func QueryHisAmountLog(c *gin.Context) {
	appG := app.Gin{C: c}

	// 获取请求参数
	var req QueryHisAmountLogReq
	if err := appG.C.ShouldBindQuery(&req); err != nil {
		logger.GetLogger().Errorf("QueryHisAmountLog failed: %s", err.Error())
		appG.Response(http.StatusBadRequest, e.INVALID_PARAMS, nil)
		return
	}

	// 查询数据
	datas := make([]QueryHisAmountLogRsp, 0)
	engine := db.GetEngine()
	s := engine.Table("HIS_TAACCOUNTLOG").
		Join("INNER", "ENUMDICITEM", "ENUMDICITEM.ENUMITEMSTATUS = 1 and ENUMDICITEM.ENUMDICID = 39 and ENUMDICITEM.ENUMITEMNAME = HIS_TAACCOUNTLOG.OPERATETYPE").
		Join("LEFT", "MARKET", "MARKET.MARKETID = HIS_TAACCOUNTLOG.MARKETID").
		Join("LEFT", "GOODS", "GOODS.GOODSID = HIS_TAACCOUNTLOG.GOODSID").
		Join("LEFT", "HIS_AUCTION_ORDERINFO", "HIS_AUCTION_ORDERINFO.GOODSID = HIS_TAACCOUNTLOG.GOODSID and HIS_AUCTION_ORDERINFO.ISVALIDDATA = 1").
		Join("LEFT", "DELIVERYGOODS", "DELIVERYGOODS.DELIVERYGOODSID = HIS_TAACCOUNTLOG.GOODSID").
		Select(`to_char(HIS_TAACCOUNTLOG.RELATIONORDERID) as RELATIONORDERID, HIS_TAACCOUNTLOG.*, 
				MARKET.MARKETNAME, MARKET.TRADEMODE, 
				GOODS.GOODSCODE, GOODS.GOODSNAME, 
				HIS_AUCTION_ORDERINFO.GOODSCODE AS AGOODSCODE, HIS_AUCTION_ORDERINFO.GOODSNAME AS AGOODSNAME, 
				DELIVERYGOODS.DELIVERYGOODSCODE AS DGOODSCODE, DELIVERYGOODS.DELIVERYGOODSNAME AS DGOODSNAME, 
				ENUMDICITEM.ENUMDICNAME AS OPERATETYPENAME`).
		Where(fmt.Sprintf(`HIS_TAACCOUNTLOG.ISVALIDDATA = 1 and HIS_TAACCOUNTLOG.ACCOUNTID in (%s)`, req.AccountID)).Desc("HIS_TAACCOUNTLOG.AUTOID")
	if len(req.OperateType) > 0 {
		s = s.And(fmt.Sprintf("HIS_TAACCOUNTLOG.OPERATETYPE in (%s)", req.OperateType))
	}
	if len(req.StartDate) > 0 {
		s = s.And(fmt.Sprintf("to_date(HIS_TAACCOUNTLOG.HISTRADEDATE,'yyyyMMdd') >= to_date('%s','yyyy-MM-dd')", req.StartDate))
	}
	if len(req.EndDate) > 0 {
		s = s.And(fmt.Sprintf("to_date(HIS_TAACCOUNTLOG.HISTRADEDATE,'yyyyMMdd') <= to_date('%s','yyyy-MM-dd')", req.EndDate))
	}
	if err := s.Find(&datas); err != nil {
		// 查询失败
		logger.GetLogger().Errorf("QueryHisAmountLog failed: %s", err.Error())
		appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil)
		return
	}

	// 查询成功返回
	if req.PageSize > 0 {
		// 分页
		rst := make([]QueryHisAmountLogRsp, 0)
		// 开始上标
		start := req.Page * req.PageSize
		// 结束下标
		end := start + req.PageSize

		if start <= len(datas) {
			// 判断结束下标是否越界
			if end > len(datas) {
				end = len(datas)
			}
			rst = datas[start:end]
		} else {
			rst = datas[0:0]
		}

		logger.GetLogger().Debugln("QueryHisAmountLog successed: %v", rst)
		appG.ResponseByPage(http.StatusOK, e.SUCCESS, rst, app.PageInfo{Page: req.Page, PageSize: req.PageSize, Total: len(datas)})
	} else {
		// 不分页
		logger.GetLogger().Debugln("QueryHisAmountLog successed: %v", datas)
		appG.Response(http.StatusOK, e.SUCCESS, datas)
	}
}
