package handlers

import (
	"encoding/json"
	"net/http"
	"time"

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

// VendorHandlers handles vendor-compliance HTTP requests
type VendorHandlers struct {
	store *vendor.Store
}

// NewVendorHandlers creates new vendor handlers
func NewVendorHandlers(store *vendor.Store) *VendorHandlers {
	return &VendorHandlers{store: store}
}

// ============================================================================
// Vendor CRUD
// ============================================================================

// CreateVendor creates a new vendor
// POST /sdk/v1/vendors
func (h *VendorHandlers) CreateVendor(c *gin.Context) {
	var req vendor.CreateVendorRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	tenantID := rbac.GetTenantID(c)
	userID := rbac.GetUserID(c)

	v := &vendor.Vendor{
		TenantID:              tenantID,
		Name:                  req.Name,
		LegalForm:             req.LegalForm,
		Country:               req.Country,
		Address:               req.Address,
		Website:               req.Website,
		ContactName:           req.ContactName,
		ContactEmail:          req.ContactEmail,
		ContactPhone:          req.ContactPhone,
		ContactDepartment:     req.ContactDepartment,
		Role:                  req.Role,
		ServiceCategory:       req.ServiceCategory,
		ServiceDescription:    req.ServiceDescription,
		DataAccessLevel:       req.DataAccessLevel,
		ProcessingLocations:   req.ProcessingLocations,
		Certifications:        req.Certifications,
		ReviewFrequency:       req.ReviewFrequency,
		ProcessingActivityIDs: req.ProcessingActivityIDs,
		TemplateID:            req.TemplateID,
		Status:                vendor.VendorStatusActive,
		CreatedBy:             userID.String(),
	}

	if err := h.store.CreateVendor(c.Request.Context(), v); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusCreated, gin.H{"vendor": v})
}

// ListVendors lists all vendors for a tenant
// GET /sdk/v1/vendors
func (h *VendorHandlers) ListVendors(c *gin.Context) {
	tenantID := rbac.GetTenantID(c)

	vendors, err := h.store.ListVendors(c.Request.Context(), tenantID.String())
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"vendors": vendors,
		"total":   len(vendors),
	})
}

// GetVendor retrieves a vendor by ID with contracts and findings
// GET /sdk/v1/vendors/:id
func (h *VendorHandlers) GetVendor(c *gin.Context) {
	tenantID := rbac.GetTenantID(c)
	id := c.Param("id")

	v, err := h.store.GetVendor(c.Request.Context(), tenantID.String(), id)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	if v == nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "vendor not found"})
		return
	}

	contracts, _ := h.store.ListContracts(c.Request.Context(), tenantID.String(), &id)
	findings, _ := h.store.ListFindings(c.Request.Context(), tenantID.String(), &id, nil)

	c.JSON(http.StatusOK, gin.H{
		"vendor":    v,
		"contracts": contracts,
		"findings":  findings,
	})
}

// UpdateVendor updates a vendor
// PUT /sdk/v1/vendors/:id
func (h *VendorHandlers) UpdateVendor(c *gin.Context) {
	tenantID := rbac.GetTenantID(c)
	id := c.Param("id")

	v, err := h.store.GetVendor(c.Request.Context(), tenantID.String(), id)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	if v == nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "vendor not found"})
		return
	}

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

	// Apply non-nil fields
	if req.Name != nil {
		v.Name = *req.Name
	}
	if req.LegalForm != nil {
		v.LegalForm = *req.LegalForm
	}
	if req.Country != nil {
		v.Country = *req.Country
	}
	if req.Address != nil {
		v.Address = req.Address
	}
	if req.Website != nil {
		v.Website = *req.Website
	}
	if req.ContactName != nil {
		v.ContactName = *req.ContactName
	}
	if req.ContactEmail != nil {
		v.ContactEmail = *req.ContactEmail
	}
	if req.ContactPhone != nil {
		v.ContactPhone = *req.ContactPhone
	}
	if req.ContactDepartment != nil {
		v.ContactDepartment = *req.ContactDepartment
	}
	if req.Role != nil {
		v.Role = *req.Role
	}
	if req.ServiceCategory != nil {
		v.ServiceCategory = *req.ServiceCategory
	}
	if req.ServiceDescription != nil {
		v.ServiceDescription = *req.ServiceDescription
	}
	if req.DataAccessLevel != nil {
		v.DataAccessLevel = *req.DataAccessLevel
	}
	if req.ProcessingLocations != nil {
		v.ProcessingLocations = req.ProcessingLocations
	}
	if req.Certifications != nil {
		v.Certifications = req.Certifications
	}
	if req.InherentRiskScore != nil {
		v.InherentRiskScore = req.InherentRiskScore
	}
	if req.ResidualRiskScore != nil {
		v.ResidualRiskScore = req.ResidualRiskScore
	}
	if req.ManualRiskAdjustment != nil {
		v.ManualRiskAdjustment = req.ManualRiskAdjustment
	}
	if req.ReviewFrequency != nil {
		v.ReviewFrequency = *req.ReviewFrequency
	}
	if req.LastReviewDate != nil {
		v.LastReviewDate = req.LastReviewDate
	}
	if req.NextReviewDate != nil {
		v.NextReviewDate = req.NextReviewDate
	}
	if req.ProcessingActivityIDs != nil {
		v.ProcessingActivityIDs = req.ProcessingActivityIDs
	}
	if req.Status != nil {
		v.Status = *req.Status
	}
	if req.TemplateID != nil {
		v.TemplateID = req.TemplateID
	}

	if err := h.store.UpdateVendor(c.Request.Context(), v); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{"vendor": v})
}

// DeleteVendor deletes a vendor
// DELETE /sdk/v1/vendors/:id
func (h *VendorHandlers) DeleteVendor(c *gin.Context) {
	tenantID := rbac.GetTenantID(c)
	id := c.Param("id")

	if err := h.store.DeleteVendor(c.Request.Context(), tenantID.String(), id); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "vendor deleted"})
}

// ============================================================================
// Contract CRUD
// ============================================================================

// CreateContract creates a new contract for a vendor
// POST /sdk/v1/vendors/contracts
func (h *VendorHandlers) CreateContract(c *gin.Context) {
	var req vendor.CreateContractRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	tenantID := rbac.GetTenantID(c)
	userID := rbac.GetUserID(c)

	contract := &vendor.Contract{
		TenantID:            tenantID,
		VendorID:            req.VendorID,
		FileName:            req.FileName,
		OriginalName:        req.OriginalName,
		MimeType:            req.MimeType,
		FileSize:            req.FileSize,
		StoragePath:         req.StoragePath,
		DocumentType:        req.DocumentType,
		Parties:             req.Parties,
		EffectiveDate:       req.EffectiveDate,
		ExpirationDate:      req.ExpirationDate,
		AutoRenewal:         req.AutoRenewal,
		RenewalNoticePeriod: req.RenewalNoticePeriod,
		Version:             req.Version,
		PreviousVersionID:   req.PreviousVersionID,
		ReviewStatus:        "PENDING",
		CreatedBy:           userID.String(),
	}

	if contract.Version == "" {
		contract.Version = "1.0"
	}

	if err := h.store.CreateContract(c.Request.Context(), contract); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusCreated, gin.H{"contract": contract})
}

// ListContracts lists contracts for a tenant
// GET /sdk/v1/vendors/contracts
func (h *VendorHandlers) ListContracts(c *gin.Context) {
	tenantID := rbac.GetTenantID(c)

	var vendorID *string
	if vid := c.Query("vendor_id"); vid != "" {
		vendorID = &vid
	}

	contracts, err := h.store.ListContracts(c.Request.Context(), tenantID.String(), vendorID)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"contracts": contracts,
		"total":     len(contracts),
	})
}

// GetContract retrieves a contract by ID
// GET /sdk/v1/vendors/contracts/:id
func (h *VendorHandlers) GetContract(c *gin.Context) {
	tenantID := rbac.GetTenantID(c)
	id := c.Param("id")

	contract, err := h.store.GetContract(c.Request.Context(), tenantID.String(), id)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	if contract == nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "contract not found"})
		return
	}

	c.JSON(http.StatusOK, gin.H{"contract": contract})
}

// UpdateContract updates a contract
// PUT /sdk/v1/vendors/contracts/:id
func (h *VendorHandlers) UpdateContract(c *gin.Context) {
	tenantID := rbac.GetTenantID(c)
	id := c.Param("id")

	contract, err := h.store.GetContract(c.Request.Context(), tenantID.String(), id)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	if contract == nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "contract not found"})
		return
	}

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

	if req.DocumentType != nil {
		contract.DocumentType = *req.DocumentType
	}
	if req.Parties != nil {
		contract.Parties = req.Parties
	}
	if req.EffectiveDate != nil {
		contract.EffectiveDate = req.EffectiveDate
	}
	if req.ExpirationDate != nil {
		contract.ExpirationDate = req.ExpirationDate
	}
	if req.AutoRenewal != nil {
		contract.AutoRenewal = *req.AutoRenewal
	}
	if req.RenewalNoticePeriod != nil {
		contract.RenewalNoticePeriod = *req.RenewalNoticePeriod
	}
	if req.ReviewStatus != nil {
		contract.ReviewStatus = *req.ReviewStatus
	}
	if req.ReviewCompletedAt != nil {
		contract.ReviewCompletedAt = req.ReviewCompletedAt
	}
	if req.ComplianceScore != nil {
		contract.ComplianceScore = req.ComplianceScore
	}
	if req.Version != nil {
		contract.Version = *req.Version
	}
	if req.ExtractedText != nil {
		contract.ExtractedText = *req.ExtractedText
	}
	if req.PageCount != nil {
		contract.PageCount = req.PageCount
	}

	if err := h.store.UpdateContract(c.Request.Context(), contract); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{"contract": contract})
}

// DeleteContract deletes a contract
// DELETE /sdk/v1/vendors/contracts/:id
func (h *VendorHandlers) DeleteContract(c *gin.Context) {
	tenantID := rbac.GetTenantID(c)
	id := c.Param("id")

	if err := h.store.DeleteContract(c.Request.Context(), tenantID.String(), id); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "contract deleted"})
}

// ============================================================================
// Finding CRUD
// ============================================================================

// CreateFinding creates a new compliance finding
// POST /sdk/v1/vendors/findings
func (h *VendorHandlers) CreateFinding(c *gin.Context) {
	var req vendor.CreateFindingRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	tenantID := rbac.GetTenantID(c)

	finding := &vendor.Finding{
		TenantID:       tenantID,
		VendorID:       req.VendorID,
		ContractID:     req.ContractID,
		FindingType:    req.FindingType,
		Category:       req.Category,
		Severity:       req.Severity,
		Title:          req.Title,
		Description:    req.Description,
		Recommendation: req.Recommendation,
		Citations:      req.Citations,
		Status:         vendor.FindingStatusOpen,
		Assignee:       req.Assignee,
		DueDate:        req.DueDate,
	}

	if err := h.store.CreateFinding(c.Request.Context(), finding); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusCreated, gin.H{"finding": finding})
}

// ListFindings lists findings for a tenant
// GET /sdk/v1/vendors/findings
func (h *VendorHandlers) ListFindings(c *gin.Context) {
	tenantID := rbac.GetTenantID(c)

	var vendorID, contractID *string
	if vid := c.Query("vendor_id"); vid != "" {
		vendorID = &vid
	}
	if cid := c.Query("contract_id"); cid != "" {
		contractID = &cid
	}

	findings, err := h.store.ListFindings(c.Request.Context(), tenantID.String(), vendorID, contractID)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"findings": findings,
		"total":    len(findings),
	})
}

// GetFinding retrieves a finding by ID
// GET /sdk/v1/vendors/findings/:id
func (h *VendorHandlers) GetFinding(c *gin.Context) {
	tenantID := rbac.GetTenantID(c)
	id := c.Param("id")

	finding, err := h.store.GetFinding(c.Request.Context(), tenantID.String(), id)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	if finding == nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "finding not found"})
		return
	}

	c.JSON(http.StatusOK, gin.H{"finding": finding})
}

// UpdateFinding updates a finding
// PUT /sdk/v1/vendors/findings/:id
func (h *VendorHandlers) UpdateFinding(c *gin.Context) {
	tenantID := rbac.GetTenantID(c)
	id := c.Param("id")

	finding, err := h.store.GetFinding(c.Request.Context(), tenantID.String(), id)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	if finding == nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "finding not found"})
		return
	}

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

	if req.FindingType != nil {
		finding.FindingType = *req.FindingType
	}
	if req.Category != nil {
		finding.Category = *req.Category
	}
	if req.Severity != nil {
		finding.Severity = *req.Severity
	}
	if req.Title != nil {
		finding.Title = *req.Title
	}
	if req.Description != nil {
		finding.Description = *req.Description
	}
	if req.Recommendation != nil {
		finding.Recommendation = *req.Recommendation
	}
	if req.Citations != nil {
		finding.Citations = req.Citations
	}
	if req.Status != nil {
		finding.Status = *req.Status
	}
	if req.Assignee != nil {
		finding.Assignee = *req.Assignee
	}
	if req.DueDate != nil {
		finding.DueDate = req.DueDate
	}
	if req.Resolution != nil {
		finding.Resolution = *req.Resolution
	}

	if err := h.store.UpdateFinding(c.Request.Context(), finding); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{"finding": finding})
}

// ResolveFinding resolves a finding with a resolution description
// POST /sdk/v1/vendors/findings/:id/resolve
func (h *VendorHandlers) ResolveFinding(c *gin.Context) {
	tenantID := rbac.GetTenantID(c)
	userID := rbac.GetUserID(c)
	id := c.Param("id")

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

	if err := h.store.ResolveFinding(c.Request.Context(), tenantID.String(), id, req.Resolution, userID.String()); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "finding resolved"})
}

// ============================================================================
// Control Instance Operations
// ============================================================================

// UpsertControlInstance creates or updates a control instance
// POST /sdk/v1/vendors/controls
func (h *VendorHandlers) UpsertControlInstance(c *gin.Context) {
	var req struct {
		VendorID           string               `json:"vendor_id" binding:"required"`
		ControlID          string               `json:"control_id" binding:"required"`
		ControlDomain      string               `json:"control_domain"`
		Status             vendor.ControlStatus  `json:"status" binding:"required"`
		EvidenceIDs        json.RawMessage       `json:"evidence_ids,omitempty"`
		Notes              string                `json:"notes,omitempty"`
		NextAssessmentDate *time.Time            `json:"next_assessment_date,omitempty"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	tenantID := rbac.GetTenantID(c)
	userID := rbac.GetUserID(c)
	now := time.Now().UTC()
	userIDStr := userID.String()

	ci := &vendor.ControlInstance{
		TenantID:           tenantID,
		ControlID:          req.ControlID,
		ControlDomain:      req.ControlDomain,
		Status:             req.Status,
		EvidenceIDs:        req.EvidenceIDs,
		Notes:              req.Notes,
		LastAssessedAt:     &now,
		LastAssessedBy:     &userIDStr,
		NextAssessmentDate: req.NextAssessmentDate,
	}

	// Parse VendorID
	vendorUUID, err := parseUUID(req.VendorID)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "invalid vendor_id"})
		return
	}
	ci.VendorID = vendorUUID

	if err := h.store.UpsertControlInstance(c.Request.Context(), ci); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{"control_instance": ci})
}

// ListControlInstances lists control instances for a vendor
// GET /sdk/v1/vendors/controls
func (h *VendorHandlers) ListControlInstances(c *gin.Context) {
	vendorID := c.Query("vendor_id")
	if vendorID == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "vendor_id query parameter is required"})
		return
	}

	tenantID := rbac.GetTenantID(c)

	instances, err := h.store.ListControlInstances(c.Request.Context(), tenantID.String(), vendorID)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"control_instances": instances,
		"total":             len(instances),
	})
}

// ============================================================================
// Template Operations
// ============================================================================

// ListTemplates lists available templates
// GET /sdk/v1/vendors/templates
func (h *VendorHandlers) ListTemplates(c *gin.Context) {
	templateType := c.DefaultQuery("type", "VENDOR")

	var category, industry *string
	if cat := c.Query("category"); cat != "" {
		category = &cat
	}
	if ind := c.Query("industry"); ind != "" {
		industry = &ind
	}

	templates, err := h.store.ListTemplates(c.Request.Context(), templateType, category, industry)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"templates": templates,
		"total":     len(templates),
	})
}

// GetTemplate retrieves a template by its template_id string
// GET /sdk/v1/vendors/templates/:templateId
func (h *VendorHandlers) GetTemplate(c *gin.Context) {
	templateID := c.Param("templateId")
	if templateID == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "template ID is required"})
		return
	}

	tmpl, err := h.store.GetTemplate(c.Request.Context(), templateID)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	if tmpl == nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "template not found"})
		return
	}

	c.JSON(http.StatusOK, gin.H{"template": tmpl})
}

// CreateTemplate creates a custom template
// POST /sdk/v1/vendors/templates
func (h *VendorHandlers) CreateTemplate(c *gin.Context) {
	var req vendor.CreateTemplateRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	tmpl := &vendor.Template{
		TemplateType:  req.TemplateType,
		TemplateID:    req.TemplateID,
		Category:      req.Category,
		NameDE:        req.NameDE,
		NameEN:        req.NameEN,
		DescriptionDE: req.DescriptionDE,
		DescriptionEN: req.DescriptionEN,
		TemplateData:  req.TemplateData,
		Industry:      req.Industry,
		Tags:          req.Tags,
		IsSystem:      req.IsSystem,
		IsActive:      true,
	}

	// Set tenant for custom (non-system) templates
	if !req.IsSystem {
		tid := rbac.GetTenantID(c).String()
		tmpl.TenantID = &tid
	}

	if err := h.store.CreateTemplate(c.Request.Context(), tmpl); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusCreated, gin.H{"template": tmpl})
}

// ApplyTemplate creates a vendor from a template
// POST /sdk/v1/vendors/templates/:templateId/apply
func (h *VendorHandlers) ApplyTemplate(c *gin.Context) {
	templateID := c.Param("templateId")
	if templateID == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "template ID is required"})
		return
	}

	tmpl, err := h.store.GetTemplate(c.Request.Context(), templateID)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	if tmpl == nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "template not found"})
		return
	}

	// Parse template_data to extract suggested vendor fields
	var templateData struct {
		ServiceCategory    string          `json:"service_category"`
		SuggestedRole      string          `json:"suggested_role"`
		DataAccessLevel    string          `json:"data_access_level"`
		ReviewFrequency    string          `json:"review_frequency"`
		Certifications     json.RawMessage `json:"certifications"`
		ProcessingLocations json.RawMessage `json:"processing_locations"`
	}
	if err := json.Unmarshal(tmpl.TemplateData, &templateData); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to parse template data"})
		return
	}

	// Optional overrides from request body
	var overrides struct {
		Name             string `json:"name"`
		Country          string `json:"country"`
		Website          string `json:"website"`
		ContactName      string `json:"contact_name"`
		ContactEmail     string `json:"contact_email"`
	}
	c.ShouldBindJSON(&overrides)

	tenantID := rbac.GetTenantID(c)
	userID := rbac.GetUserID(c)

	v := &vendor.Vendor{
		TenantID:            tenantID,
		Name:                overrides.Name,
		Country:             overrides.Country,
		Website:             overrides.Website,
		ContactName:         overrides.ContactName,
		ContactEmail:        overrides.ContactEmail,
		Role:                vendor.VendorRole(templateData.SuggestedRole),
		ServiceCategory:     templateData.ServiceCategory,
		DataAccessLevel:     templateData.DataAccessLevel,
		ReviewFrequency:     templateData.ReviewFrequency,
		Certifications:      templateData.Certifications,
		ProcessingLocations: templateData.ProcessingLocations,
		Status:              vendor.VendorStatusActive,
		TemplateID:          &templateID,
		CreatedBy:           userID.String(),
	}

	if v.Name == "" {
		v.Name = tmpl.NameDE
	}
	if v.Country == "" {
		v.Country = "DE"
	}
	if v.Role == "" {
		v.Role = vendor.VendorRoleProcessor
	}

	if err := h.store.CreateVendor(c.Request.Context(), v); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	// Increment template usage
	_ = h.store.IncrementTemplateUsage(c.Request.Context(), templateID)

	c.JSON(http.StatusCreated, gin.H{
		"vendor":      v,
		"template_id": templateID,
		"message":     "vendor created from template",
	})
}

// ============================================================================
// Statistics
// ============================================================================

// GetStatistics returns aggregated vendor statistics
// GET /sdk/v1/vendors/stats
func (h *VendorHandlers) GetStatistics(c *gin.Context) {
	tenantID := rbac.GetTenantID(c)

	stats, err := h.store.GetVendorStats(c.Request.Context(), tenantID.String())
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, stats)
}

// ============================================================================
// Helpers
// ============================================================================

func parseUUID(s string) (uuid.UUID, error) {
	return uuid.Parse(s)
}
