// Package tsdocs provides parsing and extraction for TypeScript documentation
// from typescriptlang.org.
package tsdocs

import "time"

// Module represents a TypeScript module's documentation.
type Module struct {
	Name       string       `json:"name"`
	Doc        string       `json:"doc,omitempty"`
	Version    string       `json:"version,omitempty"`
	DocURL     string       `json:"doc_url"`
	Interfaces []*Interface `json:"interfaces,omitempty"`
	Types      []*TypeAlias `json:"types,omitempty"`
	Functions  []*Function  `json:"functions,omitempty"`
	Classes    []*Class     `json:"classes,omitempty"`
	Variables  []*Variable  `json:"variables,omitempty"`
	Enums      []*Enum      `json:"enums,omitempty"`
	Namespaces []*Namespace `json:"namespaces,omitempty"`
	FetchedAt  time.Time    `json:"fetched_at"`
}

// Interface represents a TypeScript interface.
type Interface struct {
	Name            string       `json:"name"`
	Doc             string       `json:"doc,omitempty"`
	Modifiers       []string     `json:"modifiers,omitempty"`
	Extends         []string     `json:"extends,omitempty"`
	Properties      []*Property  `json:"properties,omitempty"`
	Methods         []*Method    `json:"methods,omitempty"`
	CallSignatures  []*Signature `json:"call_signatures,omitempty"`
	IndexSignatures []*Signature `json:"index_signatures,omitempty"`
	TypeParams      []*TypeParam `json:"type_params,omitempty"`
	DocURL          string       `json:"doc_url"`
	Deprecated      string       `json:"deprecated,omitempty"`
}

// TypeAlias represents a TypeScript type alias.
type TypeAlias struct {
	Name       string       `json:"name"`
	Doc        string       `json:"doc,omitempty"`
	Type       string       `json:"type"`
	TypeParams []*TypeParam `json:"type_params,omitempty"`
	DocURL     string       `json:"doc_url"`
	Deprecated string       `json:"deprecated,omitempty"`
}

// Class represents a TypeScript class.
type Class struct {
	Name         string       `json:"name"`
	Doc          string       `json:"doc,omitempty"`
	Modifiers    []string     `json:"modifiers,omitempty"`
	Extends      string       `json:"extends,omitempty"`
	Implements   []string     `json:"implements,omitempty"`
	Properties   []*Property  `json:"properties,omitempty"`
	Methods      []*Method    `json:"methods,omitempty"`
	Constructors []*Method    `json:"constructors,omitempty"`
	TypeParams   []*TypeParam `json:"type_params,omitempty"`
	DocURL       string       `json:"doc_url"`
	Deprecated   string       `json:"deprecated,omitempty"`
}

// Property represents a class or interface property.
type Property struct {
	Name       string   `json:"name"`
	Type       string   `json:"type"`
	Doc        string   `json:"doc,omitempty"`
	Modifiers  []string `json:"modifiers,omitempty"`
	Optional   bool     `json:"optional"`
	ReadOnly   bool     `json:"read_only"`
	Default    string   `json:"default,omitempty"`
	DocURL     string   `json:"doc_url"`
	Deprecated string   `json:"deprecated,omitempty"`
}

// Method represents a class or interface method.
type Method struct {
	Name       string       `json:"name"`
	Doc        string       `json:"doc,omitempty"`
	Modifiers  []string     `json:"modifiers,omitempty"`
	Parameters []*Parameter `json:"parameters,omitempty"`
	ReturnType string       `json:"return_type,omitempty"`
	TypeParams []*TypeParam `json:"type_params,omitempty"`
	Signature  string       `json:"signature"`
	DocURL     string       `json:"doc_url"`
	Deprecated string       `json:"deprecated,omitempty"`
	IsStatic   bool         `json:"is_static"`
	IsAbstract bool         `json:"is_abstract"`
}

// Function represents a standalone function.
type Function struct {
	Name       string       `json:"name"`
	Doc        string       `json:"doc,omitempty"`
	Signature  string       `json:"signature,omitempty"`
	Parameters []*Parameter `json:"parameters,omitempty"`
	ReturnType string       `json:"return_type,omitempty"`
	TypeParams []*TypeParam `json:"type_params,omitempty"`
	Signatures []*Signature `json:"signatures,omitempty"`
	DocURL     string       `json:"doc_url"`
	Deprecated string       `json:"deprecated,omitempty"`
}

// Signature represents a function/method signature.
type Signature struct {
	Parameters []*Parameter `json:"parameters,omitempty"`
	ReturnType string       `json:"return_type,omitempty"`
	Doc        string       `json:"doc,omitempty"`
}

// Parameter represents a function/method parameter.
type Parameter struct {
	Name     string `json:"name"`
	Type     string `json:"type"`
	Doc      string `json:"doc,omitempty"`
	Optional bool   `json:"optional"`
	Default  string `json:"default,omitempty"`
	Rest     bool   `json:"rest"`
}

// TypeParam represents a type parameter (generic).
type TypeParam struct {
	Name       string `json:"name"`
	Constraint string `json:"constraint,omitempty"`
	Default    string `json:"default,omitempty"`
	Doc        string `json:"doc,omitempty"`
}

// Variable represents a const/let/var declaration.
type Variable struct {
	Name       string   `json:"name"`
	Type       string   `json:"type,omitempty"`
	Value      string   `json:"value,omitempty"`
	Doc        string   `json:"doc,omitempty"`
	Modifiers  []string `json:"modifiers,omitempty"`
	DocURL     string   `json:"doc_url"`
	Deprecated string   `json:"deprecated,omitempty"`
}

// Enum represents a TypeScript enum.
type Enum struct {
	Name       string        `json:"name"`
	Doc        string        `json:"doc,omitempty"`
	Modifiers  []string      `json:"modifiers,omitempty"`
	Members    []*EnumMember `json:"members,omitempty"`
	DocURL     string        `json:"doc_url"`
	Deprecated string        `json:"deprecated,omitempty"`
}

// EnumMember represents an enum member.
type EnumMember struct {
	Name  string `json:"name"`
	Value string `json:"value,omitempty"`
	Doc   string `json:"doc,omitempty"`
}

// Namespace represents a TypeScript namespace.
type Namespace struct {
	Name       string       `json:"name"`
	Doc        string       `json:"doc,omitempty"`
	Interfaces []*Interface `json:"interfaces,omitempty"`
	Types      []*TypeAlias `json:"types,omitempty"`
	Functions  []*Function  `json:"functions,omitempty"`
	Classes    []*Class     `json:"classes,omitempty"`
	Variables  []*Variable  `json:"variables,omitempty"`
	DocURL     string       `json:"doc_url"`
}

// SearchResult represents a search result.
type SearchResult struct {
	Name   string `json:"name"`
	Kind   string `json:"kind"` // interface, type, function, class, variable, enum
	Module string `json:"module,omitempty"`
	Doc    string `json:"doc,omitempty"`
	DocURL string `json:"doc_url"`
	Score  int    `json:"score"`
}
