package flattens

import (
	"context"
	"fmt"

	"github.com/google/uuid"
	"github.com/hashicorp/terraform-plugin-framework/diag"
	"github.com/hashicorp/terraform-plugin-framework/types"
	"github.com/hashicorp/terraform-plugin-log/tflog"
	"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/client"
	"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/rg/models"
	"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/rg/utilities"
)

// RGDataSource flattens data source for rg (resource group).
// Return error in case data source is not found on the platform.
// Flatten errors are added to tflog.
func RGDataSource(ctx context.Context, state *models.DataSourceRGModel, c *client.Client) diag.Diagnostics {
	tflog.Info(ctx, "Start flattens.RGDataSource")

	diags := diag.Diagnostics{}

	rgId := uint64(state.RGID.ValueInt64())

	recordRG, err := utilities.RGCheckPresence(ctx, rgId, c)
	if err != nil {
		diags.AddError(fmt.Sprintf("Cannot get info about resource group with ID %v", rgId), err.Error())
		return diags
	}

	tflog.Info(ctx, "flattens.RGDataSource: before flatten", map[string]any{"rg_id": rgId, "recordRG": recordRG})

	id := uuid.New()
	*state = models.DataSourceRGModel{
		RGID: state.RGID,

		Timeouts: state.Timeouts,

		Id:                     types.StringValue(id.String()),
		AccountID:              types.Int64Value(int64(recordRG.AccountID)),
		GID:                    types.Int64Value(int64(recordRG.GID)),
		Name:                   types.StringValue(recordRG.Name),
		DefNetType:             types.StringValue(recordRG.DefNetType),
		Description:            types.StringValue(recordRG.Description),
		AccountName:            types.StringValue(recordRG.AccountName),
		ACL:                    flattenACL(ctx, &recordRG.ACL),
		CPUAllocationParameter: types.StringValue(recordRG.CPUAllocationParameter),
		CPUAllocationRatio:     types.Float64Value(recordRG.CPUAllocationRatio),
		CreatedBy:              types.StringValue(recordRG.CreatedBy),
		CreatedTime:            types.Int64Value(int64(recordRG.CreatedTime)),
		DefNetID:               types.Int64Value(recordRG.DefNetID),
		DeletedBy:              types.StringValue(recordRG.DeletedBy),
		DeletedTime:            types.Int64Value(int64(recordRG.DeletedTime)),
		Dirty:                  types.BoolValue(recordRG.Dirty),
		GUID:                   types.Int64Value(int64(recordRG.GUID)),
		LockStatus:             types.StringValue(recordRG.LockStatus),
		Milestones:             types.Int64Value(int64(recordRG.Milestones)),
		Secret:                 types.StringValue(recordRG.Secret),
		Status:                 types.StringValue(recordRG.Status),
		UpdatedBy:              types.StringValue(recordRG.UpdatedBy),
		UpdatedTime:            types.Int64Value(int64(recordRG.UpdatedTime)),
		ResourceLimits: &models.ResourceLimitsModel{
			CUC:      types.Float64Value(recordRG.ResourceLimits.CUC),
			CUD:      types.Float64Value(recordRG.ResourceLimits.CUD),
			CUDM:     types.Float64Value(recordRG.ResourceLimits.CUDM),
			CUI:      types.Float64Value(recordRG.ResourceLimits.CUI),
			CUM:      types.Float64Value(recordRG.ResourceLimits.CUM),
			CUNP:     types.Float64Value(recordRG.ResourceLimits.CUNP),
			GPUUnits: types.Float64Value(recordRG.ResourceLimits.GPUUnits),
		},
	}

	var diagsItem diag.Diagnostics
	state.UniqPools, diagsItem = types.ListValueFrom(ctx, types.StringType, recordRG.UniqPools)
	if diagsItem.HasError() {
		tflog.Error(ctx, fmt.Sprint("flattens.RGDataSource: cannot flatten recordRG.UniqPools to state.UniqPools", diags))
	}
	state.VINS, diagsItem = types.ListValueFrom(ctx, types.Int64Type, recordRG.VINS)
	if diagsItem.HasError() {
		tflog.Error(ctx, fmt.Sprint("flattens.RGDataSource: cannot flatten recordRG.VINS to state.VINS", diags))
	}
	state.ResTypes, diagsItem = types.ListValueFrom(ctx, types.StringType, recordRG.ResTypes)
	if diagsItem.HasError() {
		tflog.Error(ctx, fmt.Sprint("flattens.RGDataSource: cannot flatten recordRG.ResTypes to state.ResTypes", diags))
	}
	state.Computes, diagsItem = types.ListValueFrom(ctx, types.Int64Type, recordRG.Computes)
	if diagsItem.HasError() {
		tflog.Error(ctx, fmt.Sprint("flattens.RGDataSource: cannot flatten recordRG.Computes to state.Computes", diags))
	}
	state.ComputeFeatures, diagsItem = types.ListValueFrom(ctx, types.StringType, recordRG.ComputeFeatures)
	if diagsItem.HasError() {
		tflog.Error(ctx, fmt.Sprint("flattens.RGDataSource: cannot flatten recordRG.ComputeFeatures to state.ComputeFeatures", diags))
	}

	tflog.Info(ctx, "flattens.RGDataSource: after flatten", map[string]any{"rg_id": state.Id.ValueString()})

	tflog.Info(ctx, "End flattens.RGDataSource", map[string]any{"rg_id": state.Id.ValueString()})
	return nil
}
