package template

import "git.warky.dev/wdevs/relspecgo/pkg/models"

// TemplateData wraps the model data with additional context for template execution
type TemplateData struct {
	// One of these will be populated based on execution mode
	Database *models.Database
	Schema   *models.Schema
	Domain   *models.Domain
	Script   *models.Script
	Table    *models.Table

	// Context information (parent references)
	ParentSchema   *models.Schema   // Set for table/script modes
	ParentDatabase *models.Database // Always set for full database context

	// Pre-computed views for convenience
	FlatColumns       []*models.FlatColumn
	FlatTables        []*models.FlatTable
	FlatConstraints   []*models.FlatConstraint
	FlatRelationships []*models.FlatRelationship
	Summary           *models.DatabaseSummary

	// User metadata from WriterOptions
	Metadata map[string]interface{}
}

// NewDatabaseData creates template data for database mode
func NewDatabaseData(db *models.Database, metadata map[string]interface{}) *TemplateData {
	return &TemplateData{
		Database:          db,
		ParentDatabase:    db,
		FlatColumns:       db.ToFlatColumns(),
		FlatTables:        db.ToFlatTables(),
		FlatConstraints:   db.ToFlatConstraints(),
		FlatRelationships: db.ToFlatRelationships(),
		Summary:           db.ToSummary(),
		Metadata:          metadata,
	}
}

// NewSchemaData creates template data for schema mode
func NewSchemaData(schema *models.Schema, metadata map[string]interface{}) *TemplateData {
	// Create a temporary database with just this schema for context
	db := models.InitDatabase(schema.Name)
	db.Schemas = []*models.Schema{schema}

	return &TemplateData{
		Schema:            schema,
		ParentDatabase:    db,
		FlatColumns:       db.ToFlatColumns(),
		FlatTables:        db.ToFlatTables(),
		FlatConstraints:   db.ToFlatConstraints(),
		FlatRelationships: db.ToFlatRelationships(),
		Summary:           db.ToSummary(),
		Metadata:          metadata,
	}
}

// NewDomainData creates template data for domain mode
func NewDomainData(domain *models.Domain, db *models.Database, metadata map[string]interface{}) *TemplateData {
	return &TemplateData{
		Domain:         domain,
		ParentDatabase: db,
		Metadata:       metadata,
	}
}

// NewScriptData creates template data for script mode
func NewScriptData(script *models.Script, schema *models.Schema, db *models.Database, metadata map[string]interface{}) *TemplateData {
	return &TemplateData{
		Script:         script,
		ParentSchema:   schema,
		ParentDatabase: db,
		Metadata:       metadata,
	}
}

// NewTableData creates template data for table mode
func NewTableData(table *models.Table, schema *models.Schema, db *models.Database, metadata map[string]interface{}) *TemplateData {
	return &TemplateData{
		Table:          table,
		ParentSchema:   schema,
		ParentDatabase: db,
		Metadata:       metadata,
	}
}

// Name returns the primary name for the current template data (used for filename generation)
func (td *TemplateData) Name() string {
	if td.Database != nil {
		return td.Database.Name
	}
	if td.Schema != nil {
		return td.Schema.Name
	}
	if td.Domain != nil {
		return td.Domain.Name
	}
	if td.Script != nil {
		return td.Script.Name
	}
	if td.Table != nil {
		return td.Table.Name
	}
	return "output"
}
