package utilities

import (
	"context"
	"fmt"
	"strconv"
	"strings"

	"github.com/hashicorp/terraform-plugin-framework/diag"
	"github.com/hashicorp/terraform-plugin-log/tflog"
	"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/disks"
	"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/client"
	"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudbroker/disks/models"
)

// DiskSnapshotCheckPresence checks if disk snapshot exists
func DiskSnapshotCheckPresence(ctx context.Context, plan *models.ResourceDiskSnapshotModel, c *client.Client) (*disks.ItemSnapshot, diag.Diagnostics) {
	diags := diag.Diagnostics{}

	// take diskId and label from plan
	diskId := uint64(plan.DiskID.ValueInt64())
	label := plan.Label.ValueString()

	// take diskId and label from Id for imported resource
	if strings.Contains(plan.Id.ValueString(), "#") {
		diskIdInt, err := strconv.Atoi(strings.Split(plan.Id.ValueString(), "#")[0])
		if err != nil {
			diags.AddError("Cannot parse disk ID from state", err.Error())
			return nil, diags
		}
		diskId = uint64(diskIdInt)
		label = strings.Split(plan.Id.ValueString(), "#")[1]
	}

	tflog.Info(ctx, "Start DiskSnapshotCheckPresence", map[string]any{
		"disk_id": diskId,
		"label":   label,
		"id":      plan.Id.ValueString(),
	})

	tflog.Info(ctx, "DiskSnapshotCheckPresence: before call CloudBroker().Disks().Get", map[string]any{"disk_id": diskId})
	disk, err := c.CloudBroker().Disks().Get(ctx, disks.GetRequest{DiskID: diskId})
	if err != nil {
		diags.AddError(
			fmt.Sprintf("Cannot get info about disk with disk_id %d", diskId),
			err.Error(),
		)
		return nil, diags
	}
	tflog.Info(ctx, "DiskSnapshotCheckPresence: response from CloudBroker().Disks().Get", map[string]any{"response": disk})

	for _, sn := range disk.Snapshots {
		if label == sn.Label {
			return &sn, nil
		}
	}

	diags.AddError(
		"Snapshot not found",
		fmt.Sprintf("Snapshot with label %s for disk with disk_id %d not found", label, diskId),
	)
	return nil, diags
}

// RollbackDiskSnapshot rollbacks disk snapshot.
// Returns error in case of failures.
func RollbackDiskSnapshot(ctx context.Context, plan *models.ResourceDiskSnapshotModel, c *client.Client) diag.Diagnostics {
	diags := diag.Diagnostics{}

	rollbackReq := disks.SnapshotRollbackRequest{
		DiskID: uint64(plan.DiskID.ValueInt64()),
		Label:  plan.Label.ValueString(),
	}

	if !plan.TimeStamp.IsUnknown() {
		rollbackReq.TimeStamp = uint64(plan.TimeStamp.ValueInt64())
	}

	tflog.Info(ctx, "RollbackDiskSnapshot: before calling CloudBroker().Disks().SnapshotRollback", map[string]any{"req": rollbackReq})
	res, err := c.CloudBroker().Disks().SnapshotRollback(ctx, rollbackReq)
	if err != nil {
		diags.AddError(
			"RollbackDiskSnapshot: Cannot rollback snapshot",
			err.Error(),
		)
		return diags
	}
	tflog.Info(ctx, "RollbackDiskSnapshot: response from CloudBroker().Disks().SnapshotRollback", map[string]any{
		"disk_id":  plan.DiskID.ValueInt64(),
		"label":    plan.Label.ValueString(),
		"response": res})

	return nil
}
