// Package repository add by blacknc <blacknc@163.com> at 2023/03/17 18:13:56
package repository

import (
	"context"
	"dataservices/commons/errs"
	"dataservices/commons/utils"
	dto "dataservices/internal/dto/dataapi"
	"dataservices/internal/entity"

	"gorm.io/gorm/clause"
)

func CreateAppCluster(ctx context.Context, appCluster *entity.AppCluster) (*entity.AppCluster, error) {
	if err := MustFromContext(ctx).Table(entity.TableDataAppClusters).Create(appCluster).Error; err != nil {
		return nil, errs.WrapGORMError(err, "Failed to create dataapp cluster")
	}
	return appCluster, nil
}

func MultiCreateAppClusterWithIDs(ctx context.Context, dataAppID uint64, clusterIDs []uint64, operator string) error {
	appClusters := make([]entity.AppCluster, 0, len(clusterIDs))
	for _, clusterID := range clusterIDs {
		appClusters = append(appClusters, entity.AppCluster{
			DataappID: dataAppID,
			ClusterID: clusterID,
			CreatedBy: operator,
			UpdatedBy: operator,
		})
	}
	return MultiCreateAppCluster(ctx, appClusters)
}

func MultiCreateAppCluster(ctx context.Context, appClusters []entity.AppCluster) error {
	if err := MustFromContext(ctx).Table(entity.TableDataAppClusters).Create(appClusters).Error; err != nil {
		return errs.WrapGORMError(err, "Failed to create multi dataapp cluster")
	}
	return nil
}

func DeleteAppCluster(ctx context.Context, appID, clusterID uint64, operator string) error {
	data := map[string]interface{}{
		"is_deleted": 1,
		"updated_by": operator,
	}
	if err := MustFromContext(ctx).Table(entity.TableDataAppClusters).Where("dataapp_id=? AND cluster_id=?", appID, clusterID).Updates(data).Error; err != nil {
		return errs.WrapGORMError(err, "Failed to delete dataapp cluster")
	}
	return nil
}

func MultiDeleteAppCluster(ctx context.Context, appID uint64, clusterIDs []uint64, operator string) error {
	data := map[string]interface{}{
		"is_deleted": 1,
		"updated_by": operator,
	}
	if err := MustFromContext(ctx).Table(entity.TableDataAppClusters).Where("dataapp_id=? AND cluster_id in ?", appID, clusterIDs).Updates(data).Error; err != nil {
		return errs.WrapGORMError(err, "Failed to delete multi dataapp cluster")
	}
	return nil
}

func CountAppCluster(ctx context.Context, req dto.ListAppClusterReq) (int64, error) {
	txDB := MustFromContext(ctx).Table(entity.TableDataAppClusters).Where("is_deleted=0")
	if req.DataappID > 0 {
		txDB.Where("dataapp_id = ?", req.DataappID)
	}
	if req.ClusterID > 0 {
		txDB.Where("cluster_id = ?", req.ClusterID)
	}
	if len(req.ClusterIDs) > 0 {
		txDB.Where("cluster_id in ?", req.ClusterIDs)
	}
	var count int64
	if err := txDB.Count(&count).Error; err != nil {
		return 0, errs.WrapGORMError(err, "Failed to count dataapp cluster")
	}
	return count, nil
}

func ListAppClusterByAppId(ctx context.Context, appId uint64) ([]*entity.AppCluster, error) {
	var req dto.ListAppClusterReq
	req.DataappID = appId
	return ListAppCluster(ctx, req)
}

func ListAppClusterByIDs(ctx context.Context, clusterIDs []uint64) ([]*entity.AppCluster, error) {
	var req dto.ListAppClusterReq
	req.ClusterIDs = clusterIDs
	return ListAppCluster(ctx, req)
}

func ListAppCluster(ctx context.Context, req dto.ListAppClusterReq) ([]*entity.AppCluster, error) {
	var res []*entity.AppCluster
	txDB := MustFromContext(ctx).Table(entity.TableDataAppClusters).Where("is_deleted=0").Order("created_at DESC")
	if req.DataappID > 0 {
		txDB.Where("dataapp_id = ?", req.DataappID)
	}
	if req.ClusterID > 0 {
		txDB.Where("cluster_id = ?", req.ClusterID)
	}
	if len(req.ClusterIDs) > 0 {
		txDB.Where("cluster_id in ?", req.ClusterIDs)
	}
	if err := txDB.Find(&res).Error; err != nil {
		return nil, errs.WrapGORMError(err, "Failed to list dataapp cluster")
	}
	return res, nil
}

func GetAppCluster(ctx context.Context, appID, clusterID uint64) (*entity.AppCluster, error) {
	var res entity.AppCluster
	err := MustFromContext(ctx).Table(entity.TableDataAppClusters).Where("dataapp_id = ? AND cluster_id = ? AND is_deleted=0", appID, clusterID).First(&res).Error
	if err != nil {
		return nil, errs.WrapGORMError(err, "Failed to get dataapp cluster")
	}
	return &res, nil
}

func PageAppCluster(ctx context.Context, clusterIDs []uint64, offset, limit int) ([]*entity.AppCluster, error) {
	var res []*entity.AppCluster
	txDB := MustFromContext(ctx).Table(entity.TableDataAppClusters).Where("is_deleted=0").Order("created_at DESC")
	if len(clusterIDs) > 0 {
		txDB.Clauses(clause.IN{Column: "cluster_id", Values: utils.ToGeneralArr(clusterIDs...)})
	}
	if err := txDB.Offset(offset).Limit(limit).Find(&res).Error; err != nil {
		return nil, errs.WrapGORMError(err, "Failed to list dataapp cluster")
	}
	return res, nil
}
