package flattens

import (
	"context"
	"encoding/json"
	"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/decort-golang-sdk/pkg/cloudapi/image"
	"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/client"
	"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/image/models"
	"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/image/utilities"
)

func DataSourceImage(ctx context.Context, state *models.RecordImageModel, c *client.Client) diag.Diagnostics {
	tflog.Info(ctx, "Start FlattenDataSourceImage", map[string]any{"image_id": state.ImageId.ValueInt64()})

	diags := diag.Diagnostics{}

	image, err := utilities.ImageDataSourceCheckPresence(ctx, state, c)
	if err != nil {
		diags.AddError(fmt.Sprintf("Cannot get info about image with ID %d", state.ImageId.ValueInt64()), err.Error())
		return diags
	}

	id := uuid.New()
	cdPresentedTo, _ := json.Marshal(image.CdPresentedTo)

	*state = models.RecordImageModel{
		ImageId:                types.Int64Value(int64(image.ID)),
		ShowAll:                state.ShowAll,
		Timeouts:               state.Timeouts,
		Id:                     types.StringValue(id.String()),
		UNCPath:                types.StringValue(image.UNCPath),
		CKey:                   types.StringValue(image.CKey),
		AccountID:              types.Int64Value(int64(image.AccountID)),
		Architecture:           types.StringValue(image.Architecture),
		BootType:               types.StringValue(image.BootType),
		Bootable:               types.BoolValue(image.Bootable),
		ComputeCIID:            types.Int64Value(int64(image.ComputeCIID)),
		CdPresentedTo:          types.StringValue(string(cdPresentedTo)),
		GID:                    types.Int64Value(int64(image.GID)),
		DeletedTime:            types.Int64Value(int64(image.DeletedTime)),
		Description:            types.StringValue(image.Description),
		Enabled:                types.BoolValue(image.Enabled),
		GUID:                   types.Int64Value(int64(image.GUID)),
		History:                flattenHistory(ctx, &image.History),
		HotResize:              types.BoolValue(image.HotResize),
		LastModified:           types.Int64Value(int64(image.LastModified)),
		LinkTo:                 types.Int64Value(int64(image.LinkTo)),
		Milestones:             types.Int64Value(int64(image.Milestones)),
		ImageName:              types.StringValue(image.Name),
		ImageType:              types.StringValue(image.Type),
		NetworkInterfaceNaming: types.StringValue(image.NetworkInterfaceNaming),
		Password:               types.StringValue(image.Password),
		PoolName:               types.StringValue(image.Pool),
		ProviderName:           types.StringValue(image.ProviderName),
		PurgeAttempts:          types.Int64Value(int64(image.PurgeAttempts)),
		ResID:                  types.StringValue(image.ResID),
		RescueCD:               types.BoolValue(image.RescueCD),
		SepID:                  types.Int64Value(int64(image.SepID)),
		SnapshotID:             types.StringValue(image.SnapshotID),
		Size:                   types.Int64Value(int64(image.Size)),
		Status:                 types.StringValue(image.Status),
		TechStatus:             types.StringValue(image.TechStatus),
		Username:               types.StringValue(image.Username),
		Version:                types.StringValue(image.Version),
	}

	state.ACL, diags = types.ListValueFrom(ctx, types.StringType, image.ACL)
	if diags != nil {
		tflog.Error(ctx, fmt.Sprint("Error flattenACL", diags))
	}
	state.Drivers, diags = types.ListValueFrom(ctx, types.StringType, image.Drivers)
	if diags != nil {
		tflog.Error(ctx, fmt.Sprint("Error flattenDrivers", diags))
	}
	state.PresentTo, diags = types.MapValueFrom(ctx, types.Int64Type, image.PresentTo)
	if diags != nil {
		tflog.Error(ctx, fmt.Sprint("Error flattenPresentTo", diags))
	}
	state.SharedWith, diags = types.ListValueFrom(ctx, types.Int64Type, image.SharedWith)
	if diags != nil {
		tflog.Error(ctx, fmt.Sprint("Error flattenSharedWith", diags))
	}

	tflog.Info(ctx, "End FlattenDataSourceImage", map[string]any{"image_id": state.ImageId.ValueInt64()})
	return nil
}

func flattenHistory(ctx context.Context, history *image.ListHistories) []models.HistoryModel {
	tflog.Info(ctx, "Start flattenHistory")

	res := make([]models.HistoryModel, 0, len(*history))
	for _, item := range *history {
		temp := models.HistoryModel{
			GUID:      types.StringValue(item.GUID),
			ID:        types.Int64Value(int64(item.ID)),
			Timestamp: types.Int64Value(int64(item.Timestamp)),
		}
		res = append(res, temp)
	}

	tflog.Info(ctx, "End flattenHistory")
	return res
}
