package model

import (
	"errors"
	"fmt"
	"github.com/fonchain_enterprise/fonchain-approval/api/approval"
	"github.com/fonchain_enterprise/fonchain-approval/pkg/common/collection"
	m2 "github.com/fonchain_enterprise/fonchain-approval/pkg/m"
	"gorm.io/plugin/soft_delete"
	"time"
)

// Work 画作申请审批
type Work struct {
	ID            uint64                `gorm:"column:id" json:"id"`
	DeletedAt     soft_delete.DeletedAt `gorm:"column:deleted_at" json:"deletedAt"`     // 删除时间
	CreatedAt     time.Time             `gorm:"column:created_at" json:"createdAt"`     // 创建时间
	UpdatedAt     time.Time             `gorm:"column:updated_at" json:"updatedAt"`     // 更新时间
	ReturnAt      string                `gorm:"column:return_at" json:"returnAt"`       // 送还时间
	ReceivedAt    string                `gorm:"column:received_at" json:"receivedAt"`   // 领取时间
	ApprovalID    uint64                `gorm:"column:approval_id" json:"approvalId"`   // 关联申请的ID
	ApprovalWorks []*ApprovalWork       `gorm:"foreignKey:WorkID" json:"ApprovalWorks"` //type:string         comment:备注          version:2022-06-12 15:10
	ArtistUID     string                `gorm:"type:varchar(50);column:artist_uid;default:'';comment:作家id" json:"artistUID"`
}

// TableName get sql table name.获取数据库表名
func (m *Work) TableName() string {
	return "work"
}

func (m *Work) GetApproval(id uint64) (*Approval,error) {

	var entity *Approval
	if err := DB.
		Preload("ApprovalWorkFlows").
		Preload("ApprovalType").
		Preload("Work.ApprovalWorks").
		First(&entity, id).Error; err != nil {
		return entity,err
	}

	return entity,nil
}

func (m *Work) SaveApprovalContent(in *approval.CreateRequest, a *Approval) error {

	//主体保存
	m.ApprovalID = a.ID
	m.ReturnAt = in.Work.ReturnAt
	m.ReceivedAt = in.Work.ReceivedAt
	m.ArtistUID = in.Work.ArtistUID

	err := DB.Create(m).Error
	if err != nil {
		return err
	}

	//绑定画作保存
	var approvalWorks []ApprovalWork
	for _, approvalWork := range in.Work.ApprovalWorks {
		fmt.Println(approvalWork)
		temp := ApprovalWork{

			ApprovalID:    a.ID,
			WorkID:        m.ID,
			ArtworkID:     approvalWork.ArtworkID,
			ArtworkName:   approvalWork.ArtworkName,
			ArtistName:    approvalWork.ArtistName,
			ArtworkCover:  approvalWork.ArtworkCover,
			ArtworkNumber: approvalWork.ArtworkNumber,
			ArtistUID:     approvalWork.ArtistUID,
			ShowSeq:       approvalWork.ShowSeq,
		}

		approvalWorks = append(approvalWorks, temp)
	}

	if len(approvalWorks) > 0 {
		err = DB.Create(&approvalWorks).Error
	}

	return err
}

func (m *Work) UpdateApprovalContent(in *approval.CreateRequest, a *Approval) error {

	var entity *Work
	var err error

	//主体保存
	if err := DB.Where(&Work{ApprovalID: a.ID}).First(&entity).Error; err != nil {
		return errors.New(m2.ErrorNotFound)
	}

	m.ID = entity.ID
	//m.ApprovalID = a.ApproverID
	m.ReturnAt = in.Work.ReturnAt
	m.ReceivedAt = in.Work.ReceivedAt

	if err = DB.Model(&m).Updates(m).Error; err != nil {
		return err
	}

	return m.UpdateContent(in, a)
}

func (m *Work) UpdateContent(in *approval.CreateRequest, a *Approval) error {
	var oldApprovalWorks []ApprovalWork
	var oldArtWorkID []uint64
	var inArtWorkID []uint64
	var err error
	inApprovalWorkMap := make(map[uint64]*approval.ApprovalWork, len(in.Work.ApprovalWorks))

	DB.Where(&ApprovalWork{WorkID: m.ID}).Find(&oldApprovalWorks)

	for _, oldAW := range oldApprovalWorks {
		oldArtWorkID = append(oldArtWorkID, oldAW.ArtworkID)
	}

	for _, approvalWork := range in.Work.ApprovalWorks {
		inArtWorkID = append(inArtWorkID, approvalWork.ArtworkID)
		inApprovalWorkMap[approvalWork.ArtworkID] = approvalWork
	}

	needDel := collection.DiffArrayUint64(oldArtWorkID, inArtWorkID)

	if len(needDel) > 0 {
		DB.Where(&ApprovalWork{WorkID: m.ID}).Where("artwork_id in ?", needDel).
			Delete(&ApprovalWork{})
	}

	needAdd := collection.DiffArrayUint64(inArtWorkID, oldArtWorkID)

	//传递的id去除表 新增
	if len(needAdd) > 0 {
		var approvalWorks []ApprovalWork
		for _, tempId := range needAdd {
			temp := ApprovalWork{
				ApprovalID:    a.ID,
				WorkID:        m.ID,
				ArtworkID:     inApprovalWorkMap[tempId].ArtworkID,
				ArtworkName:   inApprovalWorkMap[tempId].ArtworkName,
				ArtistName:    inApprovalWorkMap[tempId].ArtistName,
				ArtworkCover:  inApprovalWorkMap[tempId].ArtworkCover,
				ArtworkNumber: inApprovalWorkMap[tempId].ArtworkNumber,
			}

			approvalWorks = append(approvalWorks, temp)
		}

		if len(approvalWorks) > 0 {
			if err = DB.Create(&approvalWorks).Error; err != nil {
				return err
			}
		}
	}

	//更新 主要修改绑定的数据权限id
	changeIds := collection.IntersectArrayUint64(inArtWorkID, oldArtWorkID)
	if len(changeIds) > 0 {
		for _, tempId := range changeIds {

			if _, ok := inApprovalWorkMap[tempId]; ok == false {
				continue
			}

			temp := ApprovalWork{
				ApprovalID:    a.ID,
				WorkID:        m.ID,
				ArtworkID:     inApprovalWorkMap[tempId].ArtworkID,
				ArtworkName:   inApprovalWorkMap[tempId].ArtworkName,
				ArtistName:    inApprovalWorkMap[tempId].ArtistName,
				ArtworkCover:  inApprovalWorkMap[tempId].ArtworkCover,
				ArtworkNumber: inApprovalWorkMap[tempId].ArtworkNumber,
			}

			DB.Model(&ApprovalWork{}).
				Where(&ApprovalWork{WorkID: m.ID, ArtworkID: inApprovalWorkMap[tempId].ArtworkID}).
				Updates(temp)
		}
	}

	return err

}

func (m *Work) BuildResContent(a *Approval, request *approval.CreateRequest) {
	if a.Work == nil {
		return
	}

	var approvalWorks []*approval.ApprovalWork

	for _, one := range a.Work.ApprovalWorks {
		temp := &approval.ApprovalWork{

			ID:            one.ID,
			WorkID:        one.WorkID,
			ApprovalID:    one.ApprovalID,
			ArtworkID:     one.ArtworkID,
			ArtworkName:   one.ArtworkName,
			ArtistName:    one.ArtistName,
			ArtworkCover:  one.ArtworkCover,
			ArtworkNumber: one.ArtworkNumber,
			ArtistUID:     one.ArtistUID,
			ShowSeq:       one.ShowSeq,
		}
		approvalWorks = append(approvalWorks, temp)

	}

	request.Work = &approval.Work{
		ID:            a.Work.ID,
		ReturnAt:      a.Work.ReturnAt,
		ReceivedAt:    a.Work.ReceivedAt,
		ApprovalWorks: approvalWorks,
		ArtistUID:     a.Work.ArtistUID,
	}
}

func (m *Work) DeleteApproval(p *Approval) error {

	var err error
	if err = DB.Where(&ApprovalWork{ApprovalID: p.ID}).
		Delete(&ApprovalWork{}).Error; err != nil {
		return err
	}

	return DB.Where(&Work{ApprovalID: p.ID}).Delete(&Work{}).Error
}