package handlers

import (
	"net/http"

	"github.com/breakpilot/ai-compliance-sdk/internal/iace"
	"github.com/gin-gonic/gin"
	"github.com/google/uuid"
)

// DeltaAnalysisRequest is the request body for POST /projects/:id/delta-analysis.
type DeltaAnalysisRequest struct {
	// Current state — if empty, loaded from project's existing components/energy
	CurrentComponents []string `json:"current_components,omitempty"`
	CurrentEnergy     []string `json:"current_energy,omitempty"`
	CurrentStates     []string `json:"current_states,omitempty"`
	CurrentRoles      []string `json:"current_roles,omitempty"`
	// Proposed additions
	AddComponents []string `json:"add_components,omitempty"`
	AddEnergy     []string `json:"add_energy,omitempty"`
	AddStates     []string `json:"add_states,omitempty"`
	AddRoles      []string `json:"add_roles,omitempty"`
	// Proposed removals
	RemoveComponents []string `json:"remove_components,omitempty"`
	RemoveEnergy     []string `json:"remove_energy,omitempty"`
	RemoveStates     []string `json:"remove_states,omitempty"`
	RemoveRoles      []string `json:"remove_roles,omitempty"`
}

// DeltaAnalysis handles POST /projects/:id/delta-analysis.
// It computes the impact of a proposed change on the hazard/measure landscape.
func (h *IACEHandler) DeltaAnalysis(c *gin.Context) {
	projectID, err := uuid.Parse(c.Param("id"))
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "invalid project ID"})
		return
	}

	var req DeltaAnalysisRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	// Build current MatchInput — from request or from project's existing data
	currentComps := req.CurrentComponents
	currentEnergy := req.CurrentEnergy
	currentStates := req.CurrentStates
	currentRoles := req.CurrentRoles

	_ = projectID // Used for future: auto-load current state from project DB

	currentInput := iace.MatchInput{
		ComponentLibraryIDs: currentComps,
		EnergySourceIDs:     currentEnergy,
		OperationalStates:   currentStates,
		HumanRoles:          currentRoles,
	}

	// Build proposed MatchInput = current + additions - removals
	proposedComps := applyDelta(currentComps, req.AddComponents, req.RemoveComponents)
	proposedEnergy := applyDelta(currentEnergy, req.AddEnergy, req.RemoveEnergy)
	proposedStates := applyDelta(currentStates, req.AddStates, req.RemoveStates)
	proposedRoles := applyDelta(currentRoles, req.AddRoles, req.RemoveRoles)

	proposedInput := iace.MatchInput{
		ComponentLibraryIDs: proposedComps,
		EnergySourceIDs:     proposedEnergy,
		OperationalStates:   proposedStates,
		HumanRoles:          proposedRoles,
	}

	// Run delta analysis
	engine := iace.NewPatternEngine()
	result := engine.DeltaMatch(currentInput, proposedInput)

	c.JSON(http.StatusOK, result)
}

// applyDelta computes: current + additions - removals
func applyDelta(current, add, remove []string) []string {
	removeSet := make(map[string]bool)
	for _, r := range remove {
		removeSet[r] = true
	}
	result := make([]string, 0, len(current)+len(add))
	seen := make(map[string]bool)
	for _, s := range current {
		if !removeSet[s] && !seen[s] {
			result = append(result, s)
			seen[s] = true
		}
	}
	for _, s := range add {
		if !seen[s] {
			result = append(result, s)
			seen[s] = true
		}
	}
	return result
}
