package deployer

import (
	"context"
	"fmt"
	"log/slog"
)

// rollback cleans up a failed deployment by removing the container,
// deleting the proxy route, and updating the instance status.
// Errors during rollback are logged but do not prevent other cleanup steps.
func (d *Deployer) rollback(ctx context.Context, deployID string, containerID string, proxyRouteID string, instanceID string) {
	d.logDeploy(deployID, "Rolling back failed deployment", "warn")

	// Remove the container if it was created.
	if containerID != "" {
		if err := d.docker.RemoveContainer(ctx, containerID, true); err != nil {
			slog.Warn("rollback: remove container", "container_id", containerID, "error", err)
			d.logDeploy(deployID, fmt.Sprintf("Rollback: failed to remove container: %v", err), "error")
		} else {
			d.logDeploy(deployID, "Rollback: container removed", "info")
		}
	}

	// Delete the proxy route if it was created.
	if proxyRouteID != "" {
		if err := d.proxy.DeleteRoute(ctx, proxyRouteID); err != nil {
			slog.Warn("rollback: delete proxy route", "route_id", proxyRouteID, "error", err)
			d.logDeploy(deployID, fmt.Sprintf("Rollback: failed to delete proxy route: %v", err), "error")
		} else {
			d.logDeploy(deployID, "Rollback: proxy route deleted", "info")
		}
	}

	// Clean up DNS record if the instance had a subdomain.
	if instanceID != "" {
		inst, err := d.store.GetInstanceByID(instanceID)
		if err == nil && inst.Subdomain != "" {
			settings, settingsErr := d.store.GetSettings()
			if settingsErr != nil {
				slog.Warn("rollback: failed to get settings for DNS cleanup", "error", settingsErr)
			} else if settings.Domain != "" {
				fqdn := inst.Subdomain + "." + settings.Domain
				d.removeDNS(ctx, fqdn, deployID)
			}
		}
	}

	// Update instance status to failed if it was created.
	if instanceID != "" {
		if err := d.store.UpdateInstanceStatus(instanceID, "failed"); err != nil {
			slog.Warn("rollback: update instance status", "instance_id", instanceID, "error", err)
		}
	}

	// Mark deploy as rolled back.
	if err := d.store.UpdateDeployStatus(deployID, "rolled_back", "deployment failed, rolled back"); err != nil {
		slog.Warn("rollback: update deploy status", "deploy_id", deployID, "error", err)
	}

	d.logDeploy(deployID, "Rollback complete", "info")
}
