package dao

import (
	"errors"
	"time"

	"github.com/fonchain/fonchain-artistinfo/cmd/model"
	"github.com/fonchain/fonchain-artistinfo/pb/contract"
	db "github.com/fonchain/fonchain-artistinfo/pkg/db"
	"github.com/fonchain/fonchain-artistinfo/pkg/m"
	"go.uber.org/zap"
)

func FinishContract(id string) (err error) {
	var contracts model.Contract
	if err = db.DB.Where("transaction_id = ?", id).First(&contracts).Error; err != nil {
		zap.L().Error("get contract info err", zap.Error(err))
		err = errors.New(m.ERROR_SELECT)
		return
	}

	if err = db.DB.Model(&contracts).Update("state", 3).Error; err != nil {
		zap.L().Error("user contract failed", zap.Error(err))
		err = errors.New(m.UPDATE_FAILED)
		return
	}

	return
}

func ContractList(req *contract.ContractListRequest) (rep *contract.ContractListRespond, err error) {
	rep = &contract.ContractListRespond{}
	var Data []*contract.ContractData

	var user model.User
	if err = db.DB.Where("id = ? ", int32(req.ID)).First(&user).Error; err != nil {
		zap.L().Error("get user info err", zap.Error(err))
		err = errors.New(m.ERROR_SELECT)
		return
	}

	var realName model.RealName
	if err = db.DB.Where("id = ? ", user.RealNameID).First(&realName).Error; err != nil {
		zap.L().Error("get realName info err", zap.Error(err))
		err = errors.New(m.ERROR_SELECT)
		return
	}

	var args []interface{}
	var sqlWhere = "user_id = ?  and type !=4 "
	args = append(args, req.ID)

	if req.State != 0 {
		sqlWhere += " and state = ? "
		if req.State == 2 {
			req.State = 3
		}
		args = append(args, req.State)
	}

	var contractModel []model.Contract
	if err = db.DB.Where(sqlWhere, args...).Find(&contractModel).Error; err != nil {
		zap.L().Error("get contractModels info err", zap.Error(err))
		err = errors.New(m.ERROR_SELECT)
		return
	}

	for _, v := range contractModel {
		contract := &contract.ContractData{}
		contract.ID = uint64(v.ID)
		contract.ContractId = v.ContractId
		contract.DownloadUrl = v.DownloadUrl
		contract.MgmtUserId = v.MgmtUserId
		contract.State = int64(v.State)
		contract.TransactionId = v.TransactionId
		contract.Type = int64(v.Type)
		contract.UserId = int64(v.UserId)
		contract.ViewUrl = v.ViewUrl
		contract.ExpirationTime = v.CreatedAt.Add(86400 * time.Second).Format("2006-01-02 15:04:05")
		contract.SignTime = v.UpdatedAt.Format("2006-01-02")
		Data = append(Data, contract)
	}

	rep.Data = Data

	return
}

func ContractTxList(req *contract.ContractTxListRequest) (rep *contract.ContractTxListRespond, err error) {
	rep = &contract.ContractTxListRespond{}
	var Data []*contract.ContractData

	var user model.User
	if err = db.DB.Where("id = ? ", int32(req.ID)).First(&user).Error; err != nil {
		zap.L().Error("get user info err", zap.Error(err))
		err = errors.New(m.ERROR_SELECT)
		return
	}

	var realName model.RealName
	if err = db.DB.Where("id = ? ", user.RealNameID).First(&realName).Error; err != nil {
		zap.L().Error("get realName info err", zap.Error(err))
		err = errors.New(m.ERROR_SELECT)
		return
	}

	var args []interface{}
	var sqlWhere = "  card_id = ? and (type = 4 or type = 7) "
	args = append(args, realName.IDNum)
	if req.State != 0 {
		sqlWhere += " and state = ? "
		args = append(args, req.State)
	}

	var contractModel []model.Contract
	if err = db.DB.Where(sqlWhere, args...).Find(&contractModel).Error; err != nil {
		zap.L().Error("get contractModels info err", zap.Error(err))
		err = errors.New(m.ERROR_SELECT)
		return
	}

	for _, v := range contractModel {
		contractTmp := &contract.ContractData{}
		contractTmp.ID = uint64(v.ID)
		contractTmp.ContractId = v.ContractId
		contractTmp.DownloadUrl = v.DownloadUrl
		contractTmp.MgmtUserId = v.MgmtUserId
		contractTmp.State = int64(v.State)
		contractTmp.TransactionId = v.TransactionId
		contractTmp.Type = int64(v.Type)
		var b string
		if v.Type == 4 {
			b = "物权"
		}
		if v.Type == 7 {
			b = "版权"
		}
		contractTmp.BatchName = b + v.BatchName[0:4] + "年" + v.BatchName[4:6] + "月" + v.BatchName[6:11] + "年" + v.BatchName[11:13] + "月"
		contractTmp.UserId = int64(v.UserId)
		contractTmp.ViewUrl = v.ViewUrl
		contractTmp.ExpirationTime = v.CreatedAt.Add(86400 * time.Second).Format("2006-01-02 15:04:05")
		contractTmp.SignTime = v.UpdatedAt.Format("2006-01-02")
		Data = append(Data, contractTmp)
	}

	rep.Data = Data

	return
}

func GetContract(id int32) (rep *contract.ContractData, err error) {
	var con model.Contract
	if err = db.DB.Where("id = ? ", id).First(&con).Error; err != nil {
		zap.L().Error("get contract info err", zap.Error(err))
		err = errors.New(m.ERROR_SELECT)
		return
	}
	rep.ID = uint64(con.ID)
	rep.UserId = int64(con.UserId)
	rep.CardId = con.CardId
	rep.MgmtUserId = con.MgmtUserId
	rep.ArtworkId = con.ArtworkId
	rep.ContractId = con.ContractId
	rep.TransactionId = con.TransactionId
	rep.Type = int64(con.Type)
	rep.BatchName = con.BatchName
	rep.ViewUrl = con.ViewUrl
	rep.DownloadUrl = con.DownloadUrl
	rep.State = int64(con.State)

	return
}

// 更新交易id
func UpdateContract(req *contract.UpdateContractRequest) error {
	//数据库操作异常
	var con model.Contract
	if err := db.DB.Model(&con).Updates(&model.Contract{ContractId: req.ContractId, ViewUrl: req.ViewUrl, DownloadUrl: req.DownloadUrl}).Error; err != nil {
		return err
	}
	return nil
}

// 更新交易id
func UpdateContractTx(txId string, contractId int32) (err error) {
	var con model.Contract
	con.ID = contractId
	if err = db.DB.Model(&con).Update("transaction_id", txId).Error; err != nil {
		return
	}
	if err = db.DB.Model(&con).Update("state", 1).Error; err != nil {
		return
	}
	return
}