package flattens

import (
	"context"
	"fmt"

	"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/bservice/models"
	"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/bservice/utilities"
)

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

	diags := diag.Diagnostics{}

	serivceId := uint64(state.ServiceId.ValueInt64())

	record, err := utilities.BServiceDataSourceCheckPresence(ctx, serivceId, c)
	if err != nil {
		diags.AddError(fmt.Sprintf("Cannot get info about bservice with ID %v", serivceId), err.Error())
		return diags
	}

	tflog.Info(ctx, "flattens.BServiceDataSource: before flatten", map[string]any{"service_id": serivceId, "record": record})

	*state = models.RecordBasicServiceModel{

		ServiceId:     state.ServiceId,
		Timeouts:      state.Timeouts,
		AccountID:     types.Int64Value(int64(record.AccountID)),
		AccountName:   types.StringValue(record.AccountName),
		BaseDomain:    types.StringValue(record.BaseDomain),
		CPUTotal:      types.Int64Value(int64(record.CPUTotal)),
		CreatedBy:     types.StringValue(record.CreatedBy),
		CreatedTime:   types.Int64Value(int64(record.CreatedTime)),
		DeletedBy:     types.StringValue(record.DeletedBy),
		DeletedTime:   types.Int64Value(int64(record.DeletedTime)),
		DiskTotal:     types.Int64Value(int64(record.DiskTotal)),
		GID:           types.Int64Value(int64(record.GID)),
		GUID:          types.Int64Value(int64(record.GUID)),
		Milestones:    types.Int64Value(int64(record.Milestones)),
		Name:          types.StringValue(record.Name),
		ParentSrvID:   types.Int64Value(int64(record.ParentSrvID)),
		ParentSrvType: types.StringValue(record.ParentSrvType),
		RAMTotal:      types.Int64Value(int64(record.RAMTotal)),
		RGID:          types.Int64Value(int64(record.RGID)),
		RGName:        types.StringValue(record.RGName),
		SSHKey:        types.StringValue(record.SSHKey),
		SSHUser:       types.StringValue(record.SSHUser),
		Status:        types.StringValue(record.Status),
		TechStatus:    types.StringValue(record.TechStatus),
		UpdatedBy:     types.StringValue(record.UpdatedBy),
		UpdatedTime:   types.Int64Value(int64(record.UpdatedTime)),
		UserManaged:   types.BoolValue(record.UserManaged),
	}

	computesList := make([]models.ItemComputeModel, 0, len(record.Computes))
	for _, v := range record.Computes {
		temp := models.ItemComputeModel{
			AccountID:     types.Int64Value(int64(v.AccountID)),
			Architecture:  types.StringValue(v.Architecture),
			CompGroupID:   types.Int64Value(int64(v.CompGroupID)),
			CompGroupName: types.StringValue(v.CompGroupName),
			CompGroupRole: types.StringValue(v.CompGroupRole),
			ID:            types.Int64Value(int64(v.ID)),
			Name:          types.StringValue(v.Name),
			RGID:          types.Int64Value(int64(v.RGID)),
			StackID:       types.Int64Value(int64(v.StackID)),
			Status:        types.StringValue(v.Status),
			TechStatus:    types.StringValue(v.TechStatus),
		}
		computesList = append(computesList, temp)
	}

	state.Computes = computesList

	groupsList := make([]models.ItemGroupModel, 0, len(record.Groups))
	for _, v := range record.Groups {
		temp := models.ItemGroupModel{
			Computes:    types.Int64Value(int64(v.Computes)),
			Consistency: types.BoolValue(v.Consistency),
			ID:          types.Int64Value(int64(v.ID)),
			Name:        types.StringValue(v.Name),
			Status:      types.StringValue(v.Status),
			TechStatus:  types.StringValue(v.TechStatus),
		}
		groupsList = append(groupsList, temp)
	}

	state.Groups = groupsList

	snapshotsList := make([]models.ItemSnapshotModel, 0, len(record.Snapshots))
	for _, v := range record.Snapshots {
		temp := models.ItemSnapshotModel{
			GUID:      types.StringValue(v.GUID),
			Label:     types.StringValue(v.Label),
			Timestamp: types.Int64Value(int64(v.Timestamp)),
			Valid:     types.BoolValue(v.Valid),
		}
		snapshotsList = append(snapshotsList, temp)
	}

	state.Snapshots = snapshotsList

	tflog.Info(ctx, "flattens.BServiceDataSource: after flatten", map[string]any{"service_id": state.ServiceId.ValueInt64()})

	tflog.Info(ctx, "End flattens.BServiceDataSource", map[string]any{"service_id": state.ServiceId.ValueInt64()})
	return nil
}
