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

// ExhibitionReward 审批-画展包润格申请
type ExhibitionReward 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 []*ApprovalReward     `gorm:"foreignKey:ExhibitionID" json:"ApprovalExhibitions"` //关联包
}

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

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

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

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

	//绑定画作保存
	var approvalExhibitions []ApprovalReward
	for _, approvalExhibition := range in.Exhibition.ApprovalExhibitions {
		temp := ApprovalReward{
			ApprovalID:    a.ID,
			ExhibitionID:  m.ID,
			PackageName:   approvalExhibition.PackageName,
			PackageID:     approvalExhibition.PackageID,
			PackageSize:   approvalExhibition.PackageSize,
			PackageNumber: approvalExhibition.PackageNumber,
			Address:       approvalExhibition.Address,
			ShowDate:      approvalExhibition.ShowDate,
			TotalPrice:    approvalExhibition.TotalPrice,
		}

		//保存包主体
		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,
				SaleAddressID:   t.SaleAddressID,
				SellSite:        t.SaleAddress,
			}
			temp.Artworks = append(temp.Artworks, art)
		}

		approvalExhibitions = append(approvalExhibitions, temp)
	}

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

	return err
}

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

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

	return entity, nil
}

func (m *ExhibitionReward) 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)
}

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

	DB.Where(&ApprovalReward{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(&ApprovalReward{ExhibitionID: m.ID}).Where("package_id in ?", needDel).
			Delete(&ApprovalReward{})
	}

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

	//传递的id去除表 新增
	if len(needAdd) > 0 {
		var approvalWorks []ApprovalReward
		for _, tempId := range needAdd {
			temp := ApprovalReward{
				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,
				TotalPrice: inApprovalExhibitionMap[tempId].TotalPrice,
			}

			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 := ApprovalReward{
				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,
				TotalPrice: inApprovalExhibitionMap[tempId].TotalPrice,
			}

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

	return err
}

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

	for _, one := range a.ExhibitionReward.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,
			TotalPrice:    one.TotalPrice,
		}

		//保存包主体
		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 {

			fmt.Println("1---", t.PriceRun, t.SellSite)
			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.ExhibitionReward.ID,
		ReceivedAt:          a.ExhibitionReward.ReceivedAt,
		ApplyID:             a.ExhibitionReward.ApplyID,
		Address:             a.ExhibitionReward.Address,
		Num:                 a.ExhibitionReward.Num,
		ApprovalExhibitions: approvalExhibitions,
	}
}

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

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

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

	return err
}