package internal

import (
	"context"
	"github.com/gogf/gf/util/guid"
	"yx-dataset-server/app/errors"
	"yx-dataset-server/app/model"
	"yx-dataset-server/app/schema"
	"yx-dataset-server/library/redis"
)

// NewOrganization 创建Organization
func NewOrganization(
	mTrans model.ITrans,
	mOrganization model.IOrganization,
	mFile model.IDatasetFile,
	mDataset model.IDataset,
	mUser model.IUser,
	mRole model.IRole,
) *Organization {
	return &Organization{
		transModel:        mTrans,
		organizationModel: mOrganization,
		fileModel:         mFile,
		datasetModel:      mDataset,
		userModel:         mUser,
		roleModel:         mRole,
	}
}

// Organization 创建Organization对象
type Organization struct {
	organizationModel model.IOrganization
	transModel        model.ITrans
	fileModel         model.IDatasetFile
	datasetModel      model.IDataset
	userModel         model.IUser
	roleModel         model.IRole
}

// Query 查询数据
func (a *Organization) Query(ctx context.Context, params schema.OrganizationQueryParam, opts ...schema.OrganizationQueryOptions) (*schema.OrganizationQueryResult, error) {
	if !CheckIsRootUser(ctx) {
		user, err := a.userModel.Get(ctx, GetUserID(ctx))
		if err != nil {
			return nil, err
		}
		role, err := a.roleModel.Get(ctx, user.RoleId)
		if err != nil {
			return nil, err
		}
		if role.Code != "11" {
			params.RecordIds = []string{user.OrgId}
		}
	}

	result, err := a.organizationModel.Query(ctx, params, opts...)
	if err != nil {
		return nil, err
	}
	if len(result.Data) > 0 {
		user, err := a.userModel.Query(ctx, schema.UserQueryParam{RecordIDs: result.Data.ToUserIds()})
		if err != nil {
			return nil, err
		}
		result.Data.FillCreator(user.Data)
	}
	for _, v := range result.Data {
		v.Used, _ = redis.GetRedisClient().Get(ctx, "chart:organization:"+v.RecordID).Int()
		v.Unused = v.ChartNum - v.Used

	}

	return result, nil
}

// Get 查询指定数据
func (a *Organization) Get(ctx context.Context, recordID string, opts ...schema.OrganizationQueryOptions) (*schema.Organization, error) {
	item, err := a.organizationModel.Get(ctx, recordID, opts...)
	if err != nil {
		return nil, err
	} else if item == nil {
		return nil, errors.ErrNotFound
	}
	user, err := a.userModel.Get(ctx, item.CreatorId)
	if err != nil {
		return nil, err
	}
	item.CreatorName = user.RealName

	item.Used, _ = redis.GetRedisClient().Get(ctx, "chart:organization:"+item.RecordID).Int()
	item.Unused = item.ChartNum - item.Used
	return item, nil
}

func (a *Organization) getUpdate(ctx context.Context, recordID string) (*schema.Organization, error) {
	return a.Get(ctx, recordID)
}

// Create 创建数据
func (a *Organization) Create(ctx context.Context, item schema.Organization) error {
	item.RecordID = guid.S()

	org, err := a.organizationModel.GetByName(ctx, item.Name)
	if err != nil {
		return err
	} else if org != nil {
		return errors.New("命名重复")
	}
	return a.organizationModel.Create(ctx, item)
}

// Update 更新数据
func (a *Organization) Update(ctx context.Context, recordID string, item schema.Organization) error {
	oldItem, err := a.organizationModel.Get(ctx, recordID)
	if err != nil {
		return err
	} else if oldItem == nil {
		return errors.ErrNotFound
	}
	return a.organizationModel.Update(ctx, recordID, item)
}

// Delete 删除数据
func (a *Organization) Delete(ctx context.Context, recordID string) error {
	err := ExecTrans(ctx, a.transModel, func(ctx context.Context) error {
		oldItem, err := a.organizationModel.Get(ctx, recordID)
		if err != nil {
			return err
		} else if oldItem == nil {
			return errors.ErrNotFound
		}

		// 删除自建知识库及相关文件
		dataset, err := a.datasetModel.Query(ctx, schema.DatasetQueryParam{OrgId: recordID})
		if err != nil {
			return err
		}
		if len(dataset.Data) > 0 {
			err = a.fileModel.DeleteByDatasetIds(ctx, dataset.Data.ToRecordIds())
			if err != nil {
				return err
			}

			err = a.datasetModel.DeleteByOrgId(ctx, recordID)
			if err != nil {
				return err
			}
		}
		return a.organizationModel.Delete(ctx, recordID)
	})
	return err
}

// UpdateStatus 更新状态
func (a *Organization) UpdateStatus(ctx context.Context, recordID string, status int) error {
	oldItem, err := a.organizationModel.Get(ctx, recordID)
	if err != nil {
		return err
	} else if oldItem == nil {
		return errors.ErrNotFound
	}
	return a.organizationModel.UpdateStatus(ctx, recordID, status)
}
