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"
)

// Exhibition 审批-画展包
type Exhibition struct {
	ID                  uint64                `gorm:"primaryKey;column:id" json:"id"`                     // 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"`                 // 更新时间
	ReceivedAt          string                `gorm:"column:received_at" json:"receivedAt"`               // 领取时间
	Address             string                `gorm:"column:address" json:"Address"`                      // 地点
	ApprovalID          uint64                `gorm:"column:approval_id" json:"approvalId"`               // 关联申请的ID
	ApplyID             string                `gorm:"size:64;column:apply_id;default:''" json:"applyID"`  // 画展包的id
	Num                 uint64                `gorm:"column:num" json:"num"`                              // 关联申请的ID
	ApprovalExhibitions []*ApprovalExhibition `gorm:"foreignKey:ExhibitionID" json:"ApprovalExhibitions"` //关联包
}

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

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

	var entity *Approval
	if err := DB.
		Preload("ApprovalWorkFlows").
		Preload("ApprovalType").
		Preload("Exhibition.ApprovalExhibitions").
		First(&entity, id).Error; err != nil {
		return entity, err
	}
	fmt.Print("结果", entity)

	return entity, nil
}

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

	fmt.Println("1--")
	//主体保存
	m.ApprovalID = a.ID
	m.ReceivedAt = in.Exhibition.ReceivedAt
	//m.Address = in.Exhibition.Address
	m.Num = uint64(len(in.Exhibition.ApprovalExhibitions))

	fmt.Println("2--")

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

	fmt.Println("3--")
	//绑定画作保存
	var approvalExhibitions []ApprovalExhibition

	fmt.Println("3--3--")
	for _, approvalExhibition := range in.Exhibition.ApprovalExhibitions {
		temp := ApprovalExhibition{
			ApprovalID:    a.ID,
			ExhibitionID:  m.ID,
			PackageName:   approvalExhibition.PackageName,
			PackageID:     approvalExhibition.PackageID,
			PackageSize:   approvalExhibition.PackageSize,
			PackageNumber: approvalExhibition.PackageNumber,
			Address:       approvalExhibition.Address,
			ShowDate:      approvalExhibition.ShowDate,
		}

		if approvalExhibition.ArtExhibitionDetail != nil {

			//保存包主体
			temp.ArtExhibitionDetail = ArtExhibitionDetail{
				ShowUID:    approvalExhibition.ArtExhibitionDetail.ShowUID,
				ShowSeq:    approvalExhibition.ArtExhibitionDetail.ShowSeq,
				ShowName:   approvalExhibition.ArtExhibitionDetail.ShowName,
				ArtistName: approvalExhibition.ArtExhibitionDetail.ArtistName,
				ArtistUID:  approvalExhibition.ArtExhibitionDetail.ArtistUID,
				ArtworkNum: approvalExhibition.ArtExhibitionDetail.ArtworkNum,
				Ruler:      approvalExhibition.ArtExhibitionDetail.Ruler,
				Price:      approvalExhibition.ArtExhibitionDetail.Price,
				Reward:     approvalExhibition.ArtExhibitionDetail.Reward,
				CreateTime: approvalExhibition.ArtExhibitionDetail.CreateTime,
				Operator:   approvalExhibition.ArtExhibitionDetail.Operator,
				IsShow:     approvalExhibition.ArtExhibitionDetail.IsShow,
				ShowTime:   approvalExhibition.ArtExhibitionDetail.ShowTime,
				Address:    approvalExhibition.ArtExhibitionDetail.Address,
			}
		}

		//画作详情
		for _, t := range approvalExhibition.Artworks {

			art := Artwork{
				ArtworkPriceUID: t.ArtworkPriceUID,
				ShowUID:         t.ShowUID,
				ArtworkUID:      t.ArtworkUID,
				ArtworkName:     t.ArtworkName,
				ArtistName:      t.ArtistName,
				Length:          t.Length,
				Width:           t.Width,
				Ruler:           t.Ruler,
				SmallPic:        t.SmallPic,
				Tfnum:           t.Tfnum,
				PriceRun:        t.Reward,
				SellSite:        t.SaleAddress,
				SaleAddressID:   t.SaleAddressID,
			}
			temp.Artworks = append(temp.Artworks, art)
		}

		approvalExhibitions = append(approvalExhibitions, temp)
	}

	fmt.Println("4--")
	if len(approvalExhibitions) > 0 {
		err = DB.Create(&approvalExhibitions).Error
	}

	return err
}

func (m *Exhibition) UpdateApprovalContent(in *approval.CreateRequest, a *Approval) error {
	var entity *Exhibition
	var err error

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

	//主体保存
	//m.ApprovalID = a.ID
	m.ReceivedAt = in.Exhibition.ReceivedAt
	//m.Address = in.Exhibition.Address
	m.Num = uint64(len(in.Exhibition.ApprovalExhibitions))
	m.ID = entity.ID

	if err = DB.Where(&Exhibition{ApprovalID: a.ID}).Updates(&m).Error; err != nil {
		return err
	}

	return m.UpdateContent(in, a)
}

func (m *Exhibition) UpdateContent(in *approval.CreateRequest, a *Approval) error {
	approvalExhibitions := in.Exhibition.ApprovalExhibitions
	var oldApprovalExhibitions []ApprovalExhibition
	var oldPackageID []string
	var inPackageID []string
	var err error
	inApprovalExhibitionMap := make(map[string]*approval.ApprovalExhibition, len(approvalExhibitions))

	DB.Where(&ApprovalExhibition{ExhibitionID: m.ID}).Find(&oldApprovalExhibitions)

	for _, oldAW := range oldApprovalExhibitions {
		oldPackageID = append(oldPackageID, oldAW.PackageID)
	}

	for _, approvalWork := range approvalExhibitions {
		inPackageID = append(inPackageID, approvalWork.PackageID)
		inApprovalExhibitionMap[approvalWork.PackageID] = approvalWork
	}

	needDel := collection.DiffArrayString(oldPackageID, inPackageID)
	fmt.Println(needDel)

	if len(needDel) > 0 {
		DB.Where(&ApprovalExhibition{ExhibitionID: m.ID}).Where("package_id in ?", needDel).
			Delete(&ApprovalExhibition{})
	}

	needAdd := collection.DiffArrayString(inPackageID, oldPackageID)
	fmt.Println(needAdd)

	//传递的id去除表 新增
	if len(needAdd) > 0 {
		var approvalWorks []ApprovalExhibition
		for _, tempId := range needAdd {
			temp := ApprovalExhibition{
				ApprovalID:   a.ID,
				ExhibitionID: m.ID,
				PackageName:  inApprovalExhibitionMap[tempId].PackageName,
				PackageID:    inApprovalExhibitionMap[tempId].PackageID,
				//PackageSize:   inApprovalExhibitionMap[tempId].PackageSize,
				//PackageNumber: inApprovalExhibitionMap[tempId].PackageNumber,
				Address:  inApprovalExhibitionMap[tempId].Address,
				ShowDate: inApprovalExhibitionMap[tempId].ShowDate,
			}

			approvalWorks = append(approvalWorks, temp)
		}

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

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

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

			temp := ApprovalExhibition{
				ApprovalID:   a.ID,
				ExhibitionID: m.ID,
				PackageName:  inApprovalExhibitionMap[tempId].PackageName,
				PackageID:    inApprovalExhibitionMap[tempId].PackageID,
				//	PackageSize:   inApprovalExhibitionMap[tempId].PackageSize,
				//	PackageNumber: inApprovalExhibitionMap[tempId].PackageNumber,
				Address:  inApprovalExhibitionMap[tempId].Address,
				ShowDate: inApprovalExhibitionMap[tempId].ShowDate,
			}

			DB.Model(&ApprovalExhibition{}).
				Where(&ApprovalExhibition{PackageID: inApprovalExhibitionMap[tempId].PackageID, ExhibitionID: m.ID}).
				Updates(temp)
		}
	}

	return err
}

func (m *Exhibition) BuildResContent(a *Approval, request *approval.CreateRequest) {
	if a.Exhibition == nil {
		return
	}
	//ApprovalWorks []*ApprovalWork `protobuf:"bytes,4,rep,name=ApprovalWorks,json=approvalWorks,proto3" json:"ApprovalWorks,omitempty"`
	var approvalExhibitions []*approval.ApprovalExhibition

	for _, one := range a.Exhibition.ApprovalExhibitions {
		temp := &approval.ApprovalExhibition{

			ID:            one.ID,
			ApprovalID:    one.ApprovalID,
			ExhibitionID:  one.ExhibitionID,
			PackageID:     one.PackageID,
			PackageName:   one.PackageName,
			PackageSize:   one.PackageSize,
			PackageNumber: one.PackageNumber,
			Address:       one.Address,
			ShowDate:      one.ShowDate,
		}

		//保存包主体
		temp.ArtExhibitionDetail = &approval.ArtExhibitionDetail{
			ShowUID:    one.ArtExhibitionDetail.ShowUID,
			ShowSeq:    one.ArtExhibitionDetail.ShowSeq,
			ShowName:   one.ArtExhibitionDetail.ShowName,
			ArtistName: one.ArtExhibitionDetail.ArtistName,
			ArtistUID:  one.ArtExhibitionDetail.ArtistUID,
			ArtworkNum: one.ArtExhibitionDetail.ArtworkNum,
			Ruler:      one.ArtExhibitionDetail.Ruler,
			Price:      one.ArtExhibitionDetail.Price,
			Reward:     one.ArtExhibitionDetail.Reward,
			CreateTime: one.ArtExhibitionDetail.CreateTime,
			Operator:   one.ArtExhibitionDetail.Operator,
			IsShow:     one.ArtExhibitionDetail.IsShow,
			ShowTime:   one.ArtExhibitionDetail.ShowTime,
			Address:    one.ArtExhibitionDetail.Address,
		}

		//画作详情
		for _, t := range one.Artworks {

			art := &approval.Artwork{
				ArtworkPriceUID: t.ArtworkPriceUID,
				ShowUID:         t.ShowUID,
				ArtworkUID:      t.ArtworkUID,
				ArtworkName:     t.ArtworkName,
				ArtistName:      t.ArtistName,
				Length:          t.Length,
				Width:           t.Width,
				Ruler:           t.Ruler,
				SmallPic:        t.SmallPic,
				Tfnum:           t.Tfnum,
				Reward:          t.PriceRun,
				SaleAddressID:   t.SaleAddressID,
				SaleAddress:     t.SellSite,
			}

			temp.Artworks = append(temp.Artworks, art)
		}

		approvalExhibitions = append(approvalExhibitions, temp)

	}

	request.Exhibition = &approval.Exhibition{
		ID:         a.Exhibition.ID,
		ReceivedAt: a.Exhibition.ReceivedAt,
		ApplyID:    a.Exhibition.ApplyID,
		//Address:    a.Exhibition.Address,
		Num:                 a.Exhibition.Num,
		ApprovalExhibitions: approvalExhibitions,
	}
}

func (m *Exhibition) DeleteApproval(p *Approval) error {
	var err error

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

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

	return err
}