package dao

import (
	"context"
	"errors"
	"strings"

	"github.com/fonchain/fonchain-artistinfo/cmd/model"
	"github.com/fonchain/fonchain-artistinfo/pb/artwork"
	"github.com/fonchain/fonchain-artistinfo/pb/contract"
	db "github.com/fonchain/fonchain-artistinfo/pkg/db"
	"github.com/fonchain/fonchain-artistinfo/pkg/m"
	"github.com/fonchain/fonchain-artistinfo/pkg/service"
	uuid "github.com/satori/go.uuid"
	"go.uber.org/zap"
	"gorm.io/gorm"
)

func GetMgmtContractByArtistUid(artistUid string, contractType int32) (err error) {
	var contract model.Contract
	if err = db.DB.Where("artist_uid = ? AND type = ?", artistUid, contractType).First(&contract).Error; err != nil && err != gorm.ErrRecordNotFound {
		zap.L().Error("get contract info err", zap.Error(err))
		err = errors.New(m.ERROR_SELECT)
		return
	}

	return
}

func CreateArtistContract(tx *gorm.DB, contract *model.Contract) (err error) {
	if err = tx.Create(contract).Error; err != nil {
		zap.L().Error("create contract err", zap.Error(err))
		err = errors.New(m.CREATE_ERROR)
		return
	}
	return
}

func GetMgmtContractByArtworkUid(artworkUid string, artworkType int32) (err error) {
	//画作有合同类型是2，6的都是 点击过"著作权代理转让服务合同"的
	var contract model.Contract

	if err = db.DB.Where("artwork_uid LiKE ? AND type = ?", "%"+artworkUid+"%", artworkType).First(&contract).Error; err != nil && err != gorm.ErrRecordNotFound {
		zap.L().Error("get contract info err", zap.Error(err))
		err = errors.New(m.ERROR_SELECT)
		return
	}

	//err 为空则查询到，返回画作合同已存在的错误
	if err == nil {
		err = errors.New(m.ARTWORK_CONTRACT_EXISTS)
	}

	return
}

func CreateArtworkContract(tx *gorm.DB, artworkUid []string, artistUid string, contractType int32, latestLockTime string) (err error) {
	var uid uuid.UUID
	if uid, err = uuid.NewV4(); err != nil {
		err = errors.New(m.ERROR_UID)
		return
	}

	//将画作切片转换成字符串格式便于保存
	ArtworkUid := strings.Join(artworkUid, ",")
	contract := &model.Contract{
		Uid:        uid.String(),
		ArtistUid:  artistUid,
		ArtworkUid: ArtworkUid,
		Type:       contractType,
		State:      1,
		Status:     2,
		LockTime:   latestLockTime,
	}
	if err = tx.Create(contract).Error; err != nil {
		zap.L().Error("create contract err", zap.Error(err))
		err = errors.New(m.CREATE_ERROR)
		return
	}

	return
}

func GetArtistNoByUid(artistUid string) (err error) {
	var user model.User
	if err = db.DB.Where("mgmt_artist_uid = ?", artistUid).First(&user).Error; err != nil {
		zap.L().Error("get user info err", zap.Error(err))
		err = errors.New(m.ERROR_SELECT)
		return
	}
	return
}

func GetContractList(artistUid string, pageSize, offset int32) (contracts []*contract.Contracts, err error) {

	var contractSlice []model.Contract
	if err = db.DB.Where("artist_uid = ?", artistUid).Order("ID asc").Limit(int(pageSize)).Offset(int(offset)).Find(&contractSlice).Error; err != nil {
		zap.L().Error("create contracts info err", zap.Error(err))
		err = errors.New(m.CREATE_ERROR)
		return
	}

	for _, v := range contractSlice {
		contcontract := &contract.Contracts{
			ContractUid:   v.Uid,
			ArtistUid:     v.ArtistUid,
			ArtworkUid:    v.ArtworkUid,
			ContractId:    v.ContractId,
			TransactionId: v.TransactionId,
			Type:          v.Type,
			ViewUrl:       v.ViewUrl,
			DownloadUrl:   v.DownloadUrl,
			State:         v.State,
			Status:        int32(v.Status),
			LockTime:      v.LockTime,
		}

		contracts = append(contracts, contcontract)
	}

	return

}

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

func ContractList(artist_uid string, state int32) (ContractData []*contract.Contracts, err error) {

	if state != 0 {
		if state == 2 {
			state = 3
		}
	}

	var contracts []model.Contract
	if err = db.DB.Where("artist_uid = ?  AND type != 4 AND  state = ?", artist_uid, state).Find(&contracts).Error; err != nil {
		zap.L().Error("get contracts info err", zap.Error(err))
		err = errors.New(m.ERROR_SELECT)
		return
	}

	for _, v := range contracts {

		Contract := &contract.Contracts{
			ContractUid:   v.Uid,
			ArtistUid:     v.ArtistUid,
			ArtworkUid:    v.ArtworkUid,
			ContractId:    v.ContractId,
			TransactionId: v.TransactionId,
			Type:          v.Type,
			ViewUrl:       v.ViewUrl,
			DownloadUrl:   v.DownloadUrl,
			State:         v.State,
			Status:        int32(v.Status),
			LockTime:      v.LockTime,
			SignTime:      v.SignTime,
		}

		ContractData = append(ContractData, Contract)
	}

	return
}

func GetContractInfo(ContractId int32) (contractInfo model.Contract, err error) {
	if err = db.DB.Where("id = ?", ContractId).First(&contractInfo).Error; err != nil {
		zap.L().Error("get contract info err", zap.Error(err))
		err = errors.New(m.ERROR_SELECT)
		return
	}
	return
}

func UpdateContract(tx *gorm.DB, artistUid, ViewPdfUrl, DownloadUrl, ContractNo string) (err error) {
	if err = tx.Model(&model.Contract{}).Where("artist_uid = ?", artistUid).Updates(model.Contract{ViewUrl: ViewPdfUrl, DownloadUrl: DownloadUrl, ContractId: ContractNo}).Error; err != nil {
		zap.L().Error("update contract info err", zap.Error(err))
		err = errors.New(m.UPDATE_FAILED)
		return
	}
	return
}

// 根据画作uid获取画作信息
func GetArtworkProfileByArtworkUid(artworkUid string) (artworkProfileInfo *artwork.ArtworkDetailResponse, err error) {
	artworkProfileInfo = &artwork.ArtworkDetailResponse{}

	artworkDetailRequest := &artwork.ArtworkDetailRequest{
		ArtworkUuid: artworkUid,
		Type:        "1",
	}
	artworkDetailResponse, err := service.ArtworkImpl.ArtworkDetail(context.Background(), artworkDetailRequest)
	if err != nil {
		return
	}
	return artworkDetailResponse, nil
}

// func FinishContract(tx *gorm.DB, id string) (contract model.Contract, err error) {
// 	if err = tx.Where("transaction_id = ?", id).First(&contract).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(&contract).Update("state", 3).Error; err != nil {
// 		zap.L().Error("user contract failed", zap.Error(err))
// 		err = errors.New(m.UPDATE_FAILED)
// 		return
// 	}

// 	return
// }

// func UpdateArtworkState(tx *gorm.DB, id int32) (err error) { //无用
// 	var artworkState model.ArtworkState
// 	if err = tx.Where("artwork_id = ? and state = ? ", id, 7).First(&artworkState).Error; err != nil {
// 		if err == gorm.ErrRecordNotFound {
// 			artworkState.ArtworkId = id
// 			artworkState.State = 7
// 			if err = tx.Create(&artworkState).Error; err != nil {
// 				zap.L().Error("create artworkState err", zap.Error(err))
// 				err = errors.New(m.CREATE_ERROR)
// 				return
// 			}
// 		} else {
// 			zap.L().Error("find artworkState info err", zap.Error(err))
// 			err = errors.New(m.ERROR_DATA_NOT_EXISTS)
// 			return
// 		}
// 	}

// 	if err = tx.Model(&model.Artwork{}).Where("id = ? ", id).Update("flow_state", 7).Error; err != nil {
// 		zap.L().Error("Artwork Update Err", zap.Error(err))
// 		err = errors.New(m.ERROR_DATA_NOT_EXISTS)
// 		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 = ? ", 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
// 	}
// 	// todo
// 	//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 { //改变交易id
// 		return
// 	}
// 	if err = db.DB.Model(&con).Update("state", 1).Error; err != nil { //更新合约状态 // 1：待生成 2 待签署 3 签署完成
// 		return
// 	}
// 	return
// }
