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

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

	diags := diag.Diagnostics{}

	serviceId := uint64(state.ServiceID.ValueInt64())

	record, err := utilities.BServiceGroupDataSourceCheckPresence(ctx, *state, c)
	if err != nil {
		diags.AddError(fmt.Sprintf("Cannot get info about group with ID %v", serviceId), err.Error())
		return diags
	}

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

	*state = models.RecordGroupModel{
		ServiceID:    state.ServiceID,
		ID:           state.ID,
		Timeouts:     state.Timeouts,
		AccountID:    types.Int64Value(int64(record.AccountID)),
		AccountName:  types.StringValue(record.AccountName),
		Consistency:  types.BoolValue(record.Consistency),
		CPU:          types.Int64Value(int64(record.CPU)),
		CreatedBy:    types.StringValue(record.CreatedBy),
		CreatedTime:  types.Int64Value(int64(record.CreatedTime)),
		DeletedBy:    types.StringValue(record.DeletedBy),
		DeletedTime:  types.Int64Value(int64(record.DeletedTime)),
		Disk:         types.Int64Value(int64(record.Disk)),
		Driver:       types.StringValue(record.Driver),
		GID:          types.Int64Value(int64(record.GID)),
		GUID:         types.Int64Value(int64(record.GUID)),
		ImageID:      types.Int64Value(int64(record.ImageID)),
		Milestones:   types.Int64Value(int64(record.Milestones)),
		Name:         types.StringValue(record.Name),
		RAM:          types.Int64Value(int64(record.RAM)),
		RGID:         types.Int64Value(int64(record.RGID)),
		RGName:       types.StringValue(record.RGName),
		Role:         types.StringValue(record.Role),
		SEPID:        types.Int64Value(int64(record.SEPID)),
		SeqNo:        types.Int64Value(int64(record.SeqNo)),
		Status:       types.StringValue(record.Status),
		TechStatus:   types.StringValue(record.TechStatus),
		TimeoutStart: types.Int64Value(int64(record.TimeoutStart)),
		UpdatedBy:    types.StringValue(record.UpdatedBy),
		UpdatedTime:  types.Int64Value(int64(record.UpdatedTime)),
	}

	// Handle computes
	computesList := make([]models.ItemGroupComputeModel, 0, len(record.Computes))
	for _, v := range record.Computes {
		ipAddresses := make([]types.String, len(v.IPAddresses))
		for i, ip := range v.IPAddresses {
			ipAddresses[i] = types.StringValue(ip)
		}

		osUsers := make([]models.ItemOSUserModel, len(v.OSUsers))
		for j, user := range v.OSUsers {
			osUsers[j] = models.ItemOSUserModel{
				Login:    types.StringValue(user.Login),
				Password: types.StringValue(user.Password),
			}
		}

		temp := models.ItemGroupComputeModel{
			ID:          types.Int64Value(int64(v.ID)),
			IPAddresses: flattens.FlattenSimpleTypeToList(ctx, types.StringType, ipAddresses),
			Name:        types.StringValue(v.Name),
			Chipset:     types.StringValue(v.Chipset),
			OSUsers:     osUsers,
		}
		computesList = append(computesList, temp)
	}

	state.Computes = computesList

	// Handle ExtNets
	extNetsList := make([]types.Int64, len(record.ExtNets))
	for i, extNet := range record.ExtNets {
		extNetsList[i] = types.Int64Value(int64(extNet))
	}
	state.ExtNets = flattens.FlattenSimpleTypeToList(ctx, types.Int64Type, extNetsList)

	// Handle Parents
	parentsList := make([]types.Int64, len(record.Parents))
	for i, parent := range record.Parents {
		parentsList[i] = types.Int64Value(int64(parent))
	}
	state.Parents = flattens.FlattenSimpleTypeToList(ctx, types.Int64Type, parentsList)

	// Handle VINSes
	vinsesList := make([]types.Int64, len(record.VINSes))
	for i, vins := range record.VINSes {
		vinsesList[i] = types.Int64Value(int64(vins))
	}
	state.VINSes = flattens.FlattenSimpleTypeToList(ctx, types.Int64Type, vinsesList)

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

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