package plugins

import (
	"context"
	"go/ast"
	"go/token"
	"go/types"

	"github.com/yourorg/devour/internal/quality"
)

// LanguagePlugin defines the interface for language-specific analysis plugins
type LanguagePlugin interface {
	// Name returns the plugin name (e.g., "go", "typescript")
	Name() string

	// Extensions returns file extensions this plugin handles
	Extensions() []string

	// MarkerFiles returns files that indicate this language (e.g., "go.mod")
	MarkerFiles() []string

	// DefaultSrcDir returns the default source directory
	DefaultSrcDir() string

	// CreateDetectors creates language-specific detectors
	CreateDetectors(finder quality.FileFinder) []quality.Detector

	// CreateFixers creates language-specific auto-fixers
	CreateFixers() []Fixer

	// AnalyzeFile performs AST analysis on a single file
	AnalyzeFile(ctx context.Context, path string, config *quality.Config) (*FileAnalysis, error)

	// BuildDependencyGraph builds the import dependency graph
	BuildDependencyGraph(ctx context.Context, path string) (*DependencyGraph, error)
}

// FileAnalysis represents the result of analyzing a single file
type FileAnalysis struct {
	Path       string
	Package    string
	Imports    []ImportInfo
	Functions  []quality.FunctionInfo
	Classes    []quality.ClassInfo
	Variables  []VariableInfo
	Types      []TypeInfo
	Comments   []CommentInfo
	LOC        int
	Complexity int
	Issues     []quality.Finding
}

// ImportInfo represents import information
type ImportInfo struct {
	Path     string
	Alias    string
	Line     int
	Used     bool
	Position token.Position
}

// VariableInfo represents variable information
type VariableInfo struct {
	Name       string
	Type       string
	File       string
	Line       int
	IsExported bool
	IsUsed     bool
}

// TypeInfo represents type information
type TypeInfo struct {
	Name       string
	Underlying string
	Methods    []string
	File       string
	Line       int
	IsExported bool
}

// CommentInfo represents comment information
type CommentInfo struct {
	Text     string
	File     string
	Line     int
	IsDoc    bool
	Attached string // What it's attached to (function name, type name, etc.)
}

// DependencyGraph represents the import dependency graph
type DependencyGraph struct {
	Packages map[string]*PackageNode
	Edges    []DependencyEdge
	Cycles   [][]string
}

// PackageNode represents a node in the dependency graph
type PackageNode struct {
	Name       string
	Path       string
	Imports    []string
	ImportedBy []string
	Files      []string
	IsLocal    bool
}

// DependencyEdge represents an edge in the dependency graph
type DependencyEdge struct {
	From string
	To   string
	Type EdgeType
}

// EdgeType represents the type of dependency edge
type EdgeType string

const (
	EdgeTypeImport   EdgeType = "import"
	EdgeTypeEmbed    EdgeType = "embed"
	EdgeTypeInternal EdgeType = "internal"
)

// Fixer defines the interface for auto-fixers
type Fixer interface {
	// Name returns the fixer name
	Name() string

	// Description returns a human-readable description
	Description() string

	// CanFix checks if this fixer can fix the given finding
	CanFix(finding quality.Finding) bool

	// Fix applies the fix and returns the patches
	Fix(ctx context.Context, finding quality.Finding, dryRun bool) (*FixResult, error)
}

// FixResult represents the result of a fix operation
type FixResult struct {
	Success  bool
	Patches  []Patch
	Message  string
	Warnings []string
}

// Patch represents a single file patch
type Patch struct {
	File    string
	OldText string
	NewText string
	Start   int
	End     int
}

// ASTInfo represents AST information for analysis
type ASTInfo struct {
	File    *ast.File
	Fset    *token.FileSet
	Types   *types.Info
	Package *types.Package
}
