package cli

import (
	"fmt"
	"strconv"
	"strings"
)

// Command parsers
func (p *Parser) parseLogout() (*Command, error) {
	cmd := NewCommand("logout")
	p.nextToken()
	// Semicolon is optional for UNSET TOKEN
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return cmd, nil
}

func (p *Parser) parseLoginUser() (*Command, error) {
	cmd := NewCommand("login_user")

	p.nextToken() // consume LOGIN
	if p.curToken.Type != TokenUser {
		return nil, fmt.Errorf("expected USER after LOGIN")
	}

	p.nextToken()
	email, err := p.parseQuotedString()
	if err != nil {
		return nil, err
	}
	cmd.Params["email"] = email

	p.nextToken()
	// Optional: PASSWORD 'password'
	if p.curToken.Type == TokenPassword {
		p.nextToken()
		password, err := p.parseQuotedString()
		if err != nil {
			return nil, err
		}
		cmd.Params["password"] = password
		p.nextToken()
	}

	// Semicolon is optional for UNSET TOKEN
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}

	return cmd, nil
}

func (p *Parser) parsePingServer() (*Command, error) {
	cmd := NewCommand("ping")
	p.nextToken()
	// Semicolon is optional for UNSET TOKEN
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return cmd, nil
}

func (p *Parser) parseRegisterCommand() (*Command, error) {
	cmd := NewCommand("register_user")

	if err := p.expectPeek(TokenUser); err != nil {
		return nil, err
	}
	p.nextToken() // consume USER

	userName, err := p.parseQuotedString()
	if err != nil {
		return nil, err
	}
	cmd.Params["user_name"] = userName
	p.nextToken() // consume Email

	if p.curToken.Type != TokenAs {
		return nil, fmt.Errorf("expected AS")
	}
	p.nextToken() // consume AS

	nickname, err := p.parseQuotedString()
	if err != nil {
		return nil, err
	}
	cmd.Params["nickname"] = nickname
	p.nextToken() // consume nickname

	if p.curToken.Type != TokenPassword {
		return nil, fmt.Errorf("expected PASSWORD")
	}
	p.nextToken() // consume PASSWORD

	password, err := p.parseQuotedString()
	if err != nil {
		return nil, err
	}
	cmd.Params["password"] = password
	p.nextToken() // consume 'password'

	// Semicolon is optional for UNSET TOKEN
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}

	return cmd, nil
}

func (p *Parser) parseListCommand() (*Command, error) {
	p.nextToken() // consume LIST

	switch p.curToken.Type {
	case TokenVars:
		p.nextToken()
		// Semicolon is optional for SHOW TOKEN
		if p.curToken.Type == TokenSemicolon {
			p.nextToken()
		}
		return NewCommand("list_variables"), nil
	case TokenConfigs:
		p.nextToken()
		// Semicolon is optional for SHOW TOKEN
		if p.curToken.Type == TokenSemicolon {
			p.nextToken()
		}
		return NewCommand("list_configs"), nil
	case TokenEnvs:
		p.nextToken()
		// Semicolon is optional for SHOW TOKEN
		if p.curToken.Type == TokenSemicolon {
			p.nextToken()
		}
		return NewCommand("list_environments"), nil
	case TokenDatasets:
		return p.parseListDatasets()
	case TokenDocuments:
		return p.parseListDatasetDocuments()
	case TokenMetadata:
		return p.parseListMetadata()
	case TokenAgents:
		return p.parseListAgents()
	case TokenTokens:
		return p.parseListTokens()
	case TokenModel:
		return p.parseListModelProviders()
	case TokenSupported:
		return p.parseListModelsOfProvider()
	case TokenModels:
		return p.parseListModelsOfProvider()
	case TokenProviders:
		return p.parseListProviders()
	case TokenInstances:
		return p.parseListInstances()
	case TokenDefault:
		return p.parseListDefaultModels()
	case TokenAvailable:
		return p.parseCommonListProviders()
	case TokenChats:
		p.nextToken()
		// Semicolon is optional for SHOW TOKEN
		if p.curToken.Type == TokenSemicolon {
			p.nextToken()
		}
		return NewCommand("list_user_chats"), nil
	case TokenFiles:
		return p.parseListFiles()
	case TokenQuotedString:
		return p.parseListQuotedStringCommand()
	default:
		return nil, fmt.Errorf("unknown LIST target: %s", p.curToken.Value)
	}
}

func (p *Parser) parseListDatasets() (*Command, error) {
	cmd := NewCommand("list_datasets")
	p.nextToken() // consume DATASETS

	// Semicolon is optional for UNSET TOKEN
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return cmd, nil
}

func (p *Parser) parseListDatasetDocuments() (*Command, error) {
	p.nextToken() // consume DOCUMENTS

	if p.curToken.Type != TokenFrom {
		return nil, fmt.Errorf("expected FROM")
	}
	p.nextToken()

	datasetID, err := p.parseQuotedString()
	if err != nil {
		return nil, err
	}
	p.nextToken()

	cmd := NewCommand("list_dataset_documents")
	cmd.Params["dataset_id"] = datasetID

	// Semicolon is optional for UNSET TOKEN
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}

	return cmd, nil
}

func (p *Parser) parseListMetadata() (*Command, error) {
	p.nextToken() // consume METADATA

	if p.curToken.Type != TokenOf {
		return nil, fmt.Errorf("expected OF after METADATA")
	}
	p.nextToken()

	if p.curToken.Type != TokenDataset {
		return nil, fmt.Errorf("expected DATASET after OF")
	}
	p.nextToken()

	// Parse dataset names (space-separated)
	var datasetNames []string
	for {
		name, err := p.parseQuotedString()
		if err != nil {
			return nil, fmt.Errorf("expected dataset name: %w", err)
		}
		datasetNames = append(datasetNames, name)

		p.nextToken()
		// Stop at semicolon or non-quoted (dataset name must be quoted)
		if p.curToken.Type == TokenSemicolon {
			break
		}
		// If next token is not a quoted string, stop parsing dataset names
		if p.curToken.Type != TokenQuotedString {
			break
		}
	}

	cmd := NewCommand("list_metadata")
	cmd.Params["dataset_names"] = datasetNames

	// Semicolon is optional
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}

	return cmd, nil
}

func (p *Parser) parseListAgents() (*Command, error) {
	p.nextToken() // consume AGENTS

	if p.curToken.Type == TokenSemicolon {
		return NewCommand("list_user_agents"), nil
	}

	if p.curToken.Type != TokenOf {
		return nil, fmt.Errorf("expected OF")
	}
	p.nextToken()

	userName, err := p.parseQuotedString()
	if err != nil {
		return nil, err
	}

	cmd := NewCommand("list_agents")
	cmd.Params["user_name"] = userName

	p.nextToken()
	// Semicolon is optional for UNSET TOKEN
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return cmd, nil
}

func (p *Parser) parseListTokens() (*Command, error) {
	p.nextToken() // consume TOKENS
	cmd := NewCommand("list_tokens")
	// Semicolon is optional for UNSET TOKEN
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return cmd, nil
}

func (p *Parser) parseListModelProviders() (*Command, error) {
	p.nextToken() // consume MODEL
	if p.curToken.Type != TokenProviders {
		return nil, fmt.Errorf("expected PROVIDERS")
	}
	p.nextToken()
	// Semicolon is optional for UNSET TOKEN
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return NewCommand("list_user_model_providers"), nil
}

// parseListProviders parses LIST PROVIDERS command
func (p *Parser) parseListProviders() (*Command, error) {
	p.nextToken() // consume PROVIDERS
	// Semicolon is optional
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return NewCommand("list_providers"), nil
}

func (p *Parser) parseListDefaultModels() (*Command, error) {
	p.nextToken() // consume DEFAULT
	if p.curToken.Type != TokenModels {
		return nil, fmt.Errorf("expected MODELS")
	}
	p.nextToken()
	// Semicolon is optional for UNSET TOKEN
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return NewCommand("list_user_default_models"), nil
}

func (p *Parser) parseListFiles() (*Command, error) {
	p.nextToken() // consume FILES
	if p.curToken.Type != TokenOf {
		return nil, fmt.Errorf("expected OF")
	}
	p.nextToken()
	if p.curToken.Type != TokenDataset {
		return nil, fmt.Errorf("expected DATASET")
	}
	p.nextToken()

	datasetName, err := p.parseQuotedString()
	if err != nil {
		return nil, err
	}

	cmd := NewCommand("list_user_dataset_files")
	cmd.Params["dataset_name"] = datasetName

	p.nextToken()
	// Semicolon is optional for UNSET TOKEN
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return cmd, nil
}

func (p *Parser) parseListQuotedStringCommand() (*Command, error) {
	str, err := p.parseQuotedString()
	if err != nil {
		return nil, err
	}
	p.nextToken() // consume str
	switch p.curToken.Type {
	case TokenTasks:
		p.nextToken() // consume TASKS
		cmd := NewCommand("list_tasks_user_command")
		cmd.Params["composite_instance_name"] = str
		return cmd, nil
	default:
		return nil, fmt.Errorf("unknown command: %s", str)
	}
}

func (p *Parser) parseShowQuotedStringCommand() (*Command, error) {
	str, err := p.parseQuotedString()
	if err != nil {
		return nil, err
	}
	p.nextToken() // consume str
	switch p.curToken.Type {
	case TokenTask:
		p.nextToken() // consume TASK

		var taskID string
		taskID, err = p.parseQuotedString()
		if err != nil {
			return nil, fmt.Errorf("expected string: %w", err)
		}
		p.nextToken()

		cmd := NewCommand("show_task_user_command")
		cmd.Params["task_id"] = taskID
		cmd.Params["composite_instance_name"] = str
		p.nextToken()

		// Semicolon is optional
		if p.curToken.Type == TokenSemicolon {
			p.nextToken()
		}
		return cmd, nil
	default:
		return nil, fmt.Errorf("unknown command: %s", str)
	}
}

func (p *Parser) parseShowCommand() (*Command, error) {
	p.nextToken() // consume SHOW
	switch p.curToken.Type {
	case TokenVersion:
		p.nextToken()
		// Semicolon is optional for SHOW TOKEN
		if p.curToken.Type == TokenSemicolon {
			p.nextToken()
		}
		return NewCommand("show_version"), nil
	case TokenToken:
		p.nextToken()
		// Semicolon is optional for SHOW TOKEN
		if p.curToken.Type == TokenSemicolon {
			p.nextToken()
		}
		return NewCommand("show_token"), nil
	case TokenCurrent:
		p.nextToken()
		if p.curToken.Type == TokenUser {
			p.nextToken()
			// Semicolon is optional for SHOW CURRENT USER
			if p.curToken.Type == TokenSemicolon {
				p.nextToken()
			}
			return NewCommand("show_current_user"), nil
		} else if p.curToken.Type == TokenModel {
			p.nextToken()
			// Semicolon is optional for SHOW CURRENT MODEL
			if p.curToken.Type == TokenSemicolon {
				p.nextToken()
			}
			return NewCommand("show_current_model"), nil
		}

		return nil, fmt.Errorf("expected USER or MODEL after CURRENT")
	case TokenUser:
		return p.parseShowUser()
	case TokenRole:
		return p.parseShowRole()
	case TokenVar:
		return p.parseShowVariable()
	case TokenService:
		return p.parseShowService()
	case TokenProvider:
		return p.parseShowProvider()
	case TokenModel:
		return p.parseShowModel()
	case TokenInstance:
		return p.parseShowInstance()
	case TokenBalance:
		return p.parseShowBalance()
	case TokenTask:
		return p.parseShowTask()
	case TokenQuotedString:
		return p.parseShowQuotedStringCommand()
	default:
		return nil, fmt.Errorf("unknown SHOW target: %s", p.curToken.Value)
	}
}

func (p *Parser) parseShowUser() (*Command, error) {
	p.nextToken() // consume USER

	// Check for PERMISSION
	if p.curToken.Type == TokenPermission {
		p.nextToken()
		userName, err := p.parseQuotedString()
		if err != nil {
			return nil, err
		}
		cmd := NewCommand("show_user_permission")
		cmd.Params["user_name"] = userName
		p.nextToken()
		// Semicolon is optional for SHOW TOKEN
		if p.curToken.Type == TokenSemicolon {
			p.nextToken()
		}
		return cmd, nil
	}

	userName, err := p.parseQuotedString()
	if err != nil {
		return nil, err
	}

	cmd := NewCommand("show_user")
	cmd.Params["user_name"] = userName

	p.nextToken()
	// Semicolon is optional for UNSET TOKEN
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return cmd, nil
}

func (p *Parser) parseShowRole() (*Command, error) {
	p.nextToken() // consume ROLE
	roleName, err := p.parseIdentifier()
	if err != nil {
		return nil, err
	}

	cmd := NewCommand("show_role")
	cmd.Params["role_name"] = roleName

	p.nextToken()
	// Semicolon is optional for UNSET TOKEN
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return cmd, nil
}

func (p *Parser) parseShowVariable() (*Command, error) {
	p.nextToken() // consume VAR
	varName, err := p.parseIdentifier()
	if err != nil {
		return nil, err
	}

	cmd := NewCommand("show_variable")
	cmd.Params["var_name"] = varName

	p.nextToken()
	// Semicolon is optional for UNSET TOKEN
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return cmd, nil
}

func (p *Parser) parseShowService() (*Command, error) {
	p.nextToken() // consume SERVICE
	serviceNum, err := p.parseNumber()
	if err != nil {
		return nil, err
	}

	cmd := NewCommand("show_service")
	cmd.Params["number"] = serviceNum

	p.nextToken()
	// Semicolon is optional for UNSET TOKEN
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return cmd, nil
}

func (p *Parser) parseShowModel() (*Command, error) {
	p.nextToken() // consume model

	modelName, err := p.parseQuotedString()
	if err != nil {
		return nil, fmt.Errorf("expected model name: %w", err)
	}

	cmd := NewCommand("show_model")
	cmd.Params["model_name"] = modelName

	p.nextToken() // consume model_name

	if p.curToken.Type != TokenFrom {
		return nil, fmt.Errorf("expected FROM")
	}
	p.nextToken() // consume from
	providerName, err := p.parseQuotedString()
	if err != nil {
		return nil, fmt.Errorf("expected provider name: %w", err)
	}
	cmd.Params["provider_name"] = providerName
	p.nextToken() // consume provider name
	// Semicolon is optional
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return cmd, nil
}

// parseShowProvider parses SHOW PROVIDER <name> command
func (p *Parser) parseShowProvider() (*Command, error) {
	p.nextToken() // consume PROVIDER

	providerName, err := p.parseQuotedString()
	if err != nil {
		return nil, fmt.Errorf("expected provider name: %w", err)
	}

	cmd := NewCommand("show_provider")
	cmd.Params["provider_name"] = providerName

	p.nextToken()
	// Semicolon is optional
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return cmd, nil
}

func (p *Parser) parseCreateCommand() (*Command, error) {
	p.nextToken() // consume CREATE

	switch p.curToken.Type {
	case TokenUser:
		return p.parseCreateUser()
	case TokenRole:
		return p.parseCreateRole()
	case TokenModel:
		return p.parseCreateModelProvider()
	case TokenDataset:
		return p.parseCreateDataset()
	case TokenChat:
		return p.parseCreateChat()
	case TokenToken:
		return p.parseCreateToken()
	case TokenChunkStore:
		return p.parseCreateChunkStore()
	case TokenMetadata:
		return p.parseCreateMetadataStore()
	case TokenProvider:
		return p.parseCreateProviderInstance()
	default:
		return nil, fmt.Errorf("unknown CREATE target: %s", p.curToken.Value)
	}
}

func (p *Parser) parseAddCommand() (*Command, error) {
	p.nextToken() // consume ADD
	switch p.curToken.Type {
	case TokenProvider:
		return p.parseAddProvider()
	case TokenModel:
		return p.parseAddModel()
	default:
		return nil, fmt.Errorf("unknown ADD target: %s", p.curToken.Value)
	}
}

func (p *Parser) parseCreateToken() (*Command, error) {
	p.nextToken() // consume TOKEN

	// Semicolon is optional for UNSET TOKEN
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}

	return NewCommand("create_token"), nil
}

// Internal CLI for GO
// parseCreateChunkStore parses: CREATE CHUNK STORE for Dataset 'name' VECTOR SIZE N
func (p *Parser) parseCreateChunkStore() (*Command, error) {
	p.nextToken() // consume CHUNK STORE compound token

	// Expect FOR
	if p.curToken.Type != TokenFor {
		return nil, fmt.Errorf("expected FOR after CHUNK STORE, got %s", p.curToken.Value)
	}
	p.nextToken()

	// Expect Dataset
	if p.curToken.Type != TokenDataset {
		return nil, fmt.Errorf("expected Dataset after FOR, got %s", p.curToken.Value)
	}
	p.nextToken()

	datasetName, err := p.parseQuotedString()
	if err != nil {
		return nil, fmt.Errorf("expected dataset name, got %s", p.curToken.Value)
	}

	p.nextToken()
	if p.curToken.Type != TokenVector {
		return nil, fmt.Errorf("expected VECTOR after dataset name, got %s", p.curToken.Value)
	}
	p.nextToken()
	if p.curToken.Type != TokenSize {
		return nil, fmt.Errorf("expected SIZE after VECTOR, got %s", p.curToken.Value)
	}
	p.nextToken()

	if p.curToken.Type != TokenInteger {
		return nil, fmt.Errorf("expected vector size number, got %s", p.curToken.Value)
	}
	vectorSize, err := strconv.Atoi(p.curToken.Value)
	if err != nil {
		return nil, fmt.Errorf("invalid vector size: %s", p.curToken.Value)
	}

	p.nextToken()
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}

	cmd := NewCommand("create_chunk_store")
	cmd.Params["dataset_name"] = datasetName
	cmd.Params["vector_size"] = vectorSize
	return cmd, nil
}

// Internal CLI for GO
// parseCreateMetadataStore parses: CREATE METADATA STORE
func (p *Parser) parseCreateMetadataStore() (*Command, error) {
	// CREATE METADATA STORE
	p.nextToken() // consume METADATA

	if p.curToken.Type != TokenStore {
		return nil, fmt.Errorf("expected STORE after METADATA, got %s", p.curToken.Value)
	}
	p.nextToken()

	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}

	return NewCommand("create_metadata_store"), nil
}

func (p *Parser) parseCreateUser() (*Command, error) {
	p.nextToken() // consume USER
	userName, err := p.parseQuotedString()
	if err != nil {
		return nil, err
	}

	p.nextToken()
	password, err := p.parseQuotedString()
	if err != nil {
		return nil, err
	}

	cmd := NewCommand("create_user")
	cmd.Params["user_name"] = userName
	cmd.Params["password"] = password
	cmd.Params["role"] = "user"

	p.nextToken()
	// Semicolon is optional for UNSET TOKEN
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return cmd, nil
}

func (p *Parser) parseCreateRole() (*Command, error) {
	p.nextToken() // consume ROLE
	roleName, err := p.parseIdentifier()
	if err != nil {
		return nil, err
	}

	cmd := NewCommand("create_role")
	cmd.Params["role_name"] = roleName

	p.nextToken()
	if p.curToken.Type == TokenDescription {
		p.nextToken()
		description, err := p.parseQuotedString()
		if err != nil {
			return nil, err
		}
		cmd.Params["description"] = description
		p.nextToken()
	}

	// Semicolon is optional for UNSET TOKEN
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return cmd, nil
}

func (p *Parser) parseCreateModelProvider() (*Command, error) {
	p.nextToken() // consume MODEL
	if p.curToken.Type != TokenProvider {
		return nil, fmt.Errorf("expected PROVIDER")
	}
	p.nextToken()

	providerName, err := p.parseQuotedString()
	if err != nil {
		return nil, err
	}

	p.nextToken()
	providerKey, err := p.parseQuotedString()
	if err != nil {
		return nil, err
	}

	cmd := NewCommand("create_model_provider")
	cmd.Params["provider_name"] = providerName
	cmd.Params["provider_key"] = providerKey

	p.nextToken()
	// Semicolon is optional for UNSET TOKEN
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return cmd, nil
}

// parseAddProvider parses ADD PROVIDER commands
// ADD PROVIDER <name>
// ADD PROVIDER <name> <api_key>
func (p *Parser) parseAddProvider() (*Command, error) {
	p.nextToken() // consume PROVIDER

	providerName, err := p.parseQuotedString()
	if err != nil {
		return nil, fmt.Errorf("expected provider name: %w", err)
	}

	cmd := NewCommand("add_provider")
	cmd.Params["provider_name"] = providerName

	p.nextToken()

	// Check if api_key is provided (optional)
	if p.curToken.Type == TokenQuotedString {
		apiKey, err := p.parseQuotedString()
		if err != nil {
			return nil, fmt.Errorf("expected api key: %w", err)
		}
		cmd.Params["api_key"] = apiKey
		p.nextToken()
	}

	// Semicolon is optional
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return cmd, nil
}

// syntax: add model 'xxx' to provider 'vllm' instance 'test' with tokens 1024 chat think vision;
func (p *Parser) parseAddModel() (*Command, error) {
	p.nextToken() // consume MODEL

	if p.curToken.Type != TokenQuotedString {
		return nil, fmt.Errorf("expected model name")
	}

	modelName, err := p.parseQuotedString()
	if err != nil {
		return nil, err
	}
	p.nextToken() // consume model name

	if p.curToken.Type != TokenTo {
		return nil, fmt.Errorf("expected TO")
	}
	p.nextToken()

	if p.curToken.Type != TokenProvider {
		return nil, fmt.Errorf("expected PROVIDER")
	}
	p.nextToken()

	// provider name
	if p.curToken.Type != TokenQuotedString {
		return nil, fmt.Errorf("expected provider name")
	}
	providerName, err := p.parseQuotedString()
	if err != nil {
		return nil, err
	}
	p.nextToken()

	if p.curToken.Type != TokenInstance {
		return nil, fmt.Errorf("expected INSTANCE")
	}
	p.nextToken()

	// instance name
	if p.curToken.Type != TokenQuotedString {
		return nil, fmt.Errorf("expected provider name")
	}
	instanceName, err := p.parseQuotedString()
	if err != nil {
		return nil, err
	}
	p.nextToken()

	var modelTypes []string
	var supportThink *bool = nil
	maxTokens := 0
	if p.curToken.Type == TokenWith {
		p.nextToken() // pass WITH
	optionsLoop:
		for {
			switch p.curToken.Type {
			case TokenThink:
				if supportThink != nil {
					return nil, fmt.Errorf("think model is already set")
				}
				supportThink = new(bool)
				p.nextToken()
				*supportThink = true
			case TokenVision:
				p.nextToken()
				modelTypes = append(modelTypes, "vision")
			case TokenChat:
				p.nextToken()
				modelTypes = append(modelTypes, "chat")
			case TokenEmbedding:
				p.nextToken()
				modelTypes = append(modelTypes, "embedding")
			case TokenRerank:
				p.nextToken()
				modelTypes = append(modelTypes, "rerank")
			case TokenOCR:
				p.nextToken()
				modelTypes = append(modelTypes, "ocr")
			case TokenDocParse:
				p.nextToken()
				modelTypes = append(modelTypes, "doc_parse")
			case TokenTTS:
				p.nextToken()
				modelTypes = append(modelTypes, "tts")
			case TokenASR:
				p.nextToken()
				modelTypes = append(modelTypes, "asr")
			case TokenTokens:
				p.nextToken() // pass TOKENS
				if maxTokens != 0 {
					return nil, fmt.Errorf("max tokens is already given %d", maxTokens)
				}
				if p.curToken.Type != TokenInteger {
					return nil, fmt.Errorf("expected integer")
				}
				maxTokens, err = p.parseNumber()
				if err != nil {
					return nil, err
				}
				p.nextToken() // consume
			case TokenSemicolon:
				p.nextToken()
				break optionsLoop // done
			default:
				// No more options to process
				break optionsLoop
			}
		}
	}

	cmd := NewCommand("add_custom_model")
	cmd.Params["model_name"] = modelName
	cmd.Params["model_types"] = modelTypes
	cmd.Params["provider_name"] = providerName
	cmd.Params["instance_name"] = instanceName
	if supportThink != nil {
		cmd.Params["support_think"] = *supportThink
	}
	cmd.Params["max_tokens"] = maxTokens

	return cmd, nil
}

func (p *Parser) parseCreateDataset() (*Command, error) {
	p.nextToken() // consume DATASET
	datasetName, err := p.parseQuotedString()
	if err != nil {
		return nil, err
	}

	p.nextToken()
	if p.curToken.Type != TokenWith {
		return nil, fmt.Errorf("expected WITH")
	}
	p.nextToken()
	if p.curToken.Type != TokenEmbedding {
		return nil, fmt.Errorf("expected EMBEDDING")
	}
	p.nextToken()

	embedding, err := p.parseQuotedString()
	if err != nil {
		return nil, err
	}

	p.nextToken()
	cmd := NewCommand("create_user_dataset")
	cmd.Params["dataset_name"] = datasetName
	cmd.Params["embedding"] = embedding

	if p.curToken.Type == TokenParser {
		p.nextToken()
		parserType, err := p.parseQuotedString()
		if err != nil {
			return nil, err
		}
		cmd.Params["parser_type"] = parserType
		p.nextToken()
	} else if p.curToken.Type == TokenPipeline {
		p.nextToken()
		pipeline, err := p.parseQuotedString()
		if err != nil {
			return nil, err
		}
		cmd.Params["pipeline"] = pipeline
		p.nextToken()
	} else {
		return nil, fmt.Errorf("expected PARSER or PIPELINE")
	}

	// Semicolon is optional for UNSET TOKEN
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return cmd, nil
}

func (p *Parser) parseCreateChat() (*Command, error) {
	p.nextToken() // consume CHAT
	chatName, err := p.parseQuotedString()
	if err != nil {
		return nil, err
	}

	cmd := NewCommand("create_user_chat")
	cmd.Params["chat_name"] = chatName

	p.nextToken()
	// Semicolon is optional for UNSET TOKEN
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return cmd, nil
}

func (p *Parser) parseDropCommand() (*Command, error) {
	p.nextToken() // consume DROP

	switch p.curToken.Type {
	case TokenUser:
		return p.parseDropUser()
	case TokenRole:
		return p.parseDropRole()
	case TokenDataset:
		return p.parseDropDataset()
	case TokenChat:
		return p.parseDropChat()
	case TokenToken:
		return p.parseDropToken()
	case TokenChunkStore:
		return p.parseDropChunkStore()
	case TokenMetadata:
		return p.parseDropMetadataStore()
	case TokenInstance:
		return p.parseDropInstance()
	case TokenModel:
		return p.parseDropInstanceModel()
	default:
		return nil, fmt.Errorf("unknown DROP target: %s", p.curToken.Value)
	}
}

func (p *Parser) parseDeleteCommand() (*Command, error) {
	p.nextToken() // consume DELETE

	switch p.curToken.Type {
	case TokenProvider:
		return p.parseDeleteProvider()
	case TokenMetadata:
		return p.parseDeleteMeta()
	default:
		return nil, fmt.Errorf("unknown DELETE target: %s", p.curToken.Value)
	}
}

func (p *Parser) parseRemoveCommand() (*Command, error) {
	p.nextToken() // consume RM

	switch p.curToken.Type {
	case TokenTag:
		return p.parseRemoveTags()
	case TokenChunks, TokenAll:
		return p.parseRemoveChunk()
	default:
		return nil, fmt.Errorf("unknown REMOVE target: %s", p.curToken.Value)
	}
}

func (p *Parser) parseDropToken() (*Command, error) {
	p.nextToken() // consume TOKEN

	tokenValue, err := p.parseQuotedString()
	if err != nil {
		return nil, err
	}

	p.nextToken()
	if p.curToken.Type != TokenOf {
		return nil, fmt.Errorf("expected OF")
	}
	p.nextToken()

	userName, err := p.parseQuotedString()
	if err != nil {
		return nil, err
	}

	cmd := NewCommand("drop_token")
	cmd.Params["token"] = tokenValue
	cmd.Params["user_name"] = userName

	p.nextToken()
	// Semicolon is optional
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return cmd, nil
}

// Internal CLI for GO
// parseDropChunkStore parses: DROP CHUNK STORE for Dataset 'name'
func (p *Parser) parseDropChunkStore() (*Command, error) {
	p.nextToken() // consume CHUNK STORE

	// Expect FOR
	if p.curToken.Type != TokenFor {
		return nil, fmt.Errorf("expected FOR after CHUNK STORE, got %s", p.curToken.Value)
	}
	p.nextToken()

	// Expect Dataset
	if p.curToken.Type != TokenDataset {
		return nil, fmt.Errorf("expected Dataset after FOR, got %s", p.curToken.Value)
	}
	p.nextToken()

	datasetName, err := p.parseQuotedString()
	if err != nil {
		return nil, fmt.Errorf("expected dataset name, got %s", p.curToken.Value)
	}

	p.nextToken()
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}

	cmd := NewCommand("drop_chunk_store")
	cmd.Params["dataset_name"] = datasetName
	return cmd, nil
}

// parseDropMetadataStore parses: DROP METADATA STORE
func (p *Parser) parseDropMetadataStore() (*Command, error) {
	// DROP METADATA STORE
	p.nextToken() // consume METADATA

	if p.curToken.Type != TokenStore {
		return nil, fmt.Errorf("expected STORE after METADATA, got %s", p.curToken.Value)
	}
	p.nextToken()
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}

	cmd := NewCommand("drop_metadata_store")
	return cmd, nil
}

func (p *Parser) parseDropUser() (*Command, error) {
	p.nextToken() // consume USER
	userName, err := p.parseQuotedString()
	if err != nil {
		return nil, err
	}

	cmd := NewCommand("drop_user")
	cmd.Params["user_name"] = userName

	p.nextToken()
	// Semicolon is optional for UNSET TOKEN
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return cmd, nil
}

func (p *Parser) parseDropRole() (*Command, error) {
	p.nextToken() // consume ROLE
	roleName, err := p.parseIdentifier()
	if err != nil {
		return nil, err
	}

	cmd := NewCommand("drop_role")
	cmd.Params["role_name"] = roleName

	p.nextToken()
	// Semicolon is optional for UNSET TOKEN
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return cmd, nil
}

// parseDeleteProvider parses DELETE PROVIDER <name> command
func (p *Parser) parseDeleteProvider() (*Command, error) {
	p.nextToken() // consume PROVIDER

	providerName, err := p.parseQuotedString()
	if err != nil {
		return nil, fmt.Errorf("expected provider name: %w", err)
	}

	cmd := NewCommand("delete_provider")
	cmd.Params["provider_name"] = providerName

	p.nextToken()
	// Semicolon is optional
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return cmd, nil
}

func (p *Parser) parseDropDataset() (*Command, error) {
	p.nextToken() // consume DATASET
	datasetName, err := p.parseQuotedString()
	if err != nil {
		return nil, err
	}

	cmd := NewCommand("drop_user_dataset")
	cmd.Params["dataset_name"] = datasetName

	p.nextToken()
	// Semicolon is optional for UNSET TOKEN
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return cmd, nil
}

func (p *Parser) parseDropChat() (*Command, error) {
	p.nextToken() // consume CHAT
	chatName, err := p.parseQuotedString()
	if err != nil {
		return nil, err
	}

	cmd := NewCommand("drop_user_chat")
	cmd.Params["chat_name"] = chatName

	p.nextToken()
	// Semicolon is optional for UNSET TOKEN
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return cmd, nil
}

func (p *Parser) parseAlterCommand() (*Command, error) {
	p.nextToken() // consume ALTER

	switch p.curToken.Type {
	case TokenUser:
		return p.parseAlterUser()
	case TokenRole:
		return p.parseAlterRole()
	case TokenProvider:
		return p.parseAlterProvider()
	case TokenInstance:
		return p.parseAlterInstance()
	default:
		return nil, fmt.Errorf("unknown ALTER target: %s", p.curToken.Value)
	}
}

func (p *Parser) parseAlterUser() (*Command, error) {
	p.nextToken() // consume USER

	if p.curToken.Type == TokenActive {
		return p.parseActivateUser()
	}

	if p.curToken.Type == TokenPassword {
		p.nextToken()
		userName, err := p.parseQuotedString()
		if err != nil {
			return nil, err
		}

		p.nextToken()
		password, err := p.parseQuotedString()
		if err != nil {
			return nil, err
		}

		cmd := NewCommand("alter_user")
		cmd.Params["user_name"] = userName
		cmd.Params["password"] = password

		p.nextToken()
		// Semicolon is optional for SHOW TOKEN
		if p.curToken.Type == TokenSemicolon {
			p.nextToken()
		}
		return cmd, nil
	}

	userName, err := p.parseQuotedString()
	if err != nil {
		return nil, err
	}

	p.nextToken()
	if p.curToken.Type != TokenSet {
		return nil, fmt.Errorf("expected SET")
	}
	p.nextToken()
	if p.curToken.Type != TokenRole {
		return nil, fmt.Errorf("expected ROLE")
	}
	p.nextToken()

	roleName, err := p.parseIdentifier()
	if err != nil {
		return nil, err
	}

	cmd := NewCommand("alter_user_role")
	cmd.Params["user_name"] = userName
	cmd.Params["role_name"] = roleName

	p.nextToken()
	// Semicolon is optional for UNSET TOKEN
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return cmd, nil
}

func (p *Parser) parseActivateUser() (*Command, error) {
	p.nextToken() // consume ACTIVE
	userName, err := p.parseQuotedString()
	if err != nil {
		return nil, err
	}

	p.nextToken()
	// Accept 'on' or 'off' as identifier
	status := p.curToken.Value
	if status != "on" && status != "off" {
		return nil, fmt.Errorf("expected 'on' or 'off', got %s", p.curToken.Value)
	}

	cmd := NewCommand("activate_user")
	cmd.Params["user_name"] = userName
	cmd.Params["activate_status"] = status

	p.nextToken()
	// Semicolon is optional for UNSET TOKEN
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return cmd, nil
}

func (p *Parser) parseAlterRole() (*Command, error) {
	p.nextToken() // consume ROLE
	roleName, err := p.parseIdentifier()
	if err != nil {
		return nil, err
	}

	p.nextToken()
	if p.curToken.Type != TokenSet {
		return nil, fmt.Errorf("expected SET")
	}
	p.nextToken()
	if p.curToken.Type != TokenDescription {
		return nil, fmt.Errorf("expected DESCRIPTION")
	}
	p.nextToken()

	description, err := p.parseQuotedString()
	if err != nil {
		return nil, err
	}

	cmd := NewCommand("alter_role")
	cmd.Params["role_name"] = roleName
	cmd.Params["description"] = description

	p.nextToken()
	// Semicolon is optional for UNSET TOKEN
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return cmd, nil
}

// parseAlterProvider parses ALTER PROVIDER <name> NAME <new_name> command
func (p *Parser) parseAlterProvider() (*Command, error) {
	p.nextToken() // consume PROVIDER

	providerName, err := p.parseQuotedString()
	if err != nil {
		return nil, fmt.Errorf("expected provider name: %w", err)
	}

	p.nextToken()
	if p.curToken.Type != TokenName {
		return nil, fmt.Errorf("expected NAME")
	}
	p.nextToken()

	newName, err := p.parseQuotedString()
	if err != nil {
		return nil, fmt.Errorf("expected new provider name: %w", err)
	}

	cmd := NewCommand("alter_provider")
	cmd.Params["provider_name"] = providerName
	cmd.Params["new_name"] = newName

	p.nextToken()
	// Semicolon is optional
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return cmd, nil
}

// parseCreateProviderInstance parses CREATE PROVIDER <name> INSTANCE <instance_name> KEY <api_key> URL <base_url> command
// instance_name cannot be "default"
func (p *Parser) parseCreateProviderInstance() (*Command, error) {
	p.nextToken() // consume PROVIDER

	providerName, err := p.parseQuotedString()
	if err != nil {
		return nil, fmt.Errorf("expected provider name: %w", err)
	}

	p.nextToken()
	if p.curToken.Type != TokenInstance {
		return nil, fmt.Errorf("expected INSTANCE after provider name")
	}
	p.nextToken()

	instanceName, err := p.parseQuotedString()
	if err != nil {
		return nil, fmt.Errorf("expected instance name: %w", err)
	}

	p.nextToken()

	if p.curToken.Type != TokenKey {
		return nil, fmt.Errorf("expected KEY after instance name")
	}
	p.nextToken()

	apiKey, err := p.parseQuotedString()
	if err != nil {
		return nil, fmt.Errorf("expected API key: %w", err)
	}
	p.nextToken()

	baseURL := ""
	if p.curToken.Type == TokenURL {
		p.nextToken()
		baseURL, err = p.parseQuotedString()
		if err != nil {
			return nil, fmt.Errorf("expected base URL: %w", err)
		}
		p.nextToken()
	}

	region := ""
	if p.curToken.Type == TokenRegion {
		p.nextToken()
		region, err = p.parseQuotedString()
		if err != nil {
			return nil, fmt.Errorf("expected base URL: %w", err)
		}
		p.nextToken()
	}

	cmd := NewCommand("create_provider_instance")
	cmd.Params["provider_name"] = providerName
	cmd.Params["instance_name"] = instanceName
	cmd.Params["api_key"] = apiKey
	if baseURL != "" {
		// Only local model provider need to set URL
		cmd.Params["base_url"] = baseURL
		if region == "" {
			region = instanceName
		}
	}

	if region != "" {
		cmd.Params["region"] = region
	}

	p.nextToken()
	// Semicolon is optional
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return cmd, nil
}

// parseListInstances parses LIST INSTANCES FROM PROVIDER <name> command
func (p *Parser) parseListInstances() (*Command, error) {
	p.nextToken() // consume INSTANCES

	if p.curToken.Type != TokenFrom {
		return nil, fmt.Errorf("expected FROM")
	}
	p.nextToken()

	providerName, err := p.parseQuotedString()
	if err != nil {
		return nil, fmt.Errorf("expected provider name after FROM PROVIDER: %w", err)
	}

	cmd := NewCommand("list_provider_instances")
	cmd.Params["provider_name"] = providerName

	p.nextToken()
	// Semicolon is optional
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return cmd, nil
}

// parseShowInstance parses SHOW INSTANCE <name> FROM PROVIDER <name> command
func (p *Parser) parseShowInstance() (*Command, error) {
	p.nextToken() // consume INSTANCE

	instanceName, err := p.parseQuotedString()
	if err != nil {
		return nil, fmt.Errorf("expected instance name: %w", err)
	}

	p.nextToken()
	if p.curToken.Type != TokenFrom {
		return nil, fmt.Errorf("expected FROM")
	}
	p.nextToken()

	providerName, err := p.parseQuotedString()
	if err != nil {
		return nil, fmt.Errorf("expected provider name after FROM PROVIDER: %w", err)
	}

	cmd := NewCommand("show_provider_instance")
	cmd.Params["instance_name"] = instanceName
	cmd.Params["provider_name"] = providerName

	p.nextToken()
	// Semicolon is optional
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return cmd, nil
}

// parseShowBalance parses SHOW BALANCE FROM <provider_name> <instance_name>
func (p *Parser) parseShowBalance() (*Command, error) {
	p.nextToken() // consume INSTANCE

	if p.curToken.Type != TokenFrom {
		return nil, fmt.Errorf("expected FROM")
	}
	p.nextToken()

	if p.curToken.Type != TokenQuotedString {
		return nil, fmt.Errorf("expected provider name after FROM PROVIDER")
	}
	providerName, err := p.parseQuotedString()
	if err != nil {
		return nil, fmt.Errorf("expected provider name after FROM PROVIDER: %w", err)
	}
	p.nextToken()

	if p.curToken.Type != TokenQuotedString {
		return nil, fmt.Errorf("expected instance name")
	}
	instanceName, err := p.parseQuotedString()
	if err != nil {
		return nil, fmt.Errorf("expected instance name: %w", err)
	}
	p.nextToken()

	cmd := NewCommand("show_instance_balance")
	cmd.Params["instance_name"] = instanceName
	cmd.Params["provider_name"] = providerName

	p.nextToken()
	// Semicolon is optional
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return cmd, nil
}

// parseShowTask parses SHOW TASK <task>
func (p *Parser) parseShowTask() (*Command, error) {
	p.nextToken() // consume TASK

	taskID, err := p.parseQuotedString()
	if err != nil {
		return nil, fmt.Errorf("expected string: %w", err)
	}
	p.nextToken()

	cmd := NewCommand("show_task_user_command")
	cmd.Params["task_id"] = taskID
	p.nextToken()

	// Semicolon is optional
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return cmd, nil
}

// parseAlterInstance parses ALTER INSTANCE <name> NAME <new_name> FROM PROVIDER <name> command
func (p *Parser) parseAlterInstance() (*Command, error) {
	p.nextToken() // consume INSTANCE

	instanceName, err := p.parseQuotedString()
	if err != nil {
		return nil, fmt.Errorf("expected instance name: %w", err)
	}

	p.nextToken()
	if p.curToken.Type != TokenName {
		return nil, fmt.Errorf("expected NAME")
	}
	p.nextToken()

	newName, err := p.parseQuotedString()
	if err != nil {
		return nil, fmt.Errorf("expected new instance name: %w", err)
	}

	p.nextToken()
	if p.curToken.Type != TokenFrom {
		return nil, fmt.Errorf("expected FROM")
	}
	p.nextToken()

	if p.curToken.Type != TokenProvider {
		return nil, fmt.Errorf("expected PROVIDER after FROM")
	}
	p.nextToken()

	providerName, err := p.parseQuotedString()
	if err != nil {
		return nil, fmt.Errorf("expected provider name after FROM PROVIDER: %w", err)
	}

	cmd := NewCommand("alter_provider_instance")
	cmd.Params["instance_name"] = instanceName
	cmd.Params["new_name"] = newName
	cmd.Params["provider_name"] = providerName

	p.nextToken()
	// Semicolon is optional
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return cmd, nil
}

// parseDropInstance parses DROP INSTANCE <name> FROM PROVIDER <name> command
func (p *Parser) parseDropInstance() (*Command, error) {
	p.nextToken() // consume INSTANCE

	instanceName, err := p.parseQuotedString()
	if err != nil {
		return nil, fmt.Errorf("expected instance name: %w", err)
	}

	p.nextToken()
	if p.curToken.Type != TokenFrom {
		return nil, fmt.Errorf("expected FROM")
	}
	p.nextToken()

	providerName, err := p.parseQuotedString()
	if err != nil {
		return nil, fmt.Errorf("expected provider name after FROM PROVIDER: %w", err)
	}

	cmd := NewCommand("drop_provider_instance")
	cmd.Params["instance_name"] = instanceName
	cmd.Params["provider_name"] = providerName

	p.nextToken()
	// Semicolon is optional
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return cmd, nil
}

// parseDropInstanceModel parses DROP MODEL <name> FROM <provider_name> <instance_name> command
// Only works for local deployed model
func (p *Parser) parseDropInstanceModel() (*Command, error) {
	p.nextToken() // consume MODEL

	modelName, err := p.parseQuotedString()
	if err != nil {
		return nil, fmt.Errorf("expected instance name: %w", err)
	}
	p.nextToken()

	if p.curToken.Type != TokenFrom {
		return nil, fmt.Errorf("expected FROM")
	}
	p.nextToken()

	providerName, err := p.parseQuotedString()
	if err != nil {
		return nil, fmt.Errorf("expected provider name after FROM PROVIDER: %w", err)
	}
	p.nextToken()

	instanceName, err := p.parseQuotedString()
	if err != nil {
		return nil, fmt.Errorf("expected instance name after provider name: %w", err)
	}
	p.nextToken()

	cmd := NewCommand("drop_instance_model")
	cmd.Params["instance_name"] = instanceName
	cmd.Params["provider_name"] = providerName
	cmd.Params["model_name"] = modelName

	p.nextToken()
	// Semicolon is optional
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return cmd, nil
}

func (p *Parser) parseGrantCommand() (*Command, error) {
	p.nextToken() // consume GRANT

	if p.curToken.Type == TokenAdmin {
		return p.parseGrantAdmin()
	}

	return p.parseGrantPermission()
}

func (p *Parser) parseGrantAdmin() (*Command, error) {
	p.nextToken() // consume ADMIN
	userName, err := p.parseQuotedString()
	if err != nil {
		return nil, err
	}

	cmd := NewCommand("grant_admin")
	cmd.Params["user_name"] = userName

	p.nextToken()
	// Semicolon is optional for UNSET TOKEN
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return cmd, nil
}

func (p *Parser) parseGrantPermission() (*Command, error) {
	actions, err := p.parseIdentifierList()
	if err != nil {
		return nil, err
	}

	if p.curToken.Type != TokenOn {
		return nil, fmt.Errorf("expected ON")
	}
	p.nextToken()

	resource, err := p.parseIdentifier()
	if err != nil {
		return nil, err
	}

	p.nextToken()
	if p.curToken.Type != TokenTo {
		return nil, fmt.Errorf("expected TO")
	}
	p.nextToken()
	if p.curToken.Type != TokenRole {
		return nil, fmt.Errorf("expected ROLE")
	}
	p.nextToken()

	roleName, err := p.parseIdentifier()
	if err != nil {
		return nil, err
	}

	cmd := NewCommand("grant_permission")
	cmd.Params["actions"] = actions
	cmd.Params["resource"] = resource
	cmd.Params["role_name"] = roleName

	p.nextToken()
	// Semicolon is optional for UNSET TOKEN
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return cmd, nil
}

func (p *Parser) parseRevokeCommand() (*Command, error) {
	p.nextToken() // consume REVOKE

	if p.curToken.Type == TokenAdmin {
		return p.parseRevokeAdmin()
	}

	return p.parseRevokePermission()
}

func (p *Parser) parseRevokeAdmin() (*Command, error) {
	p.nextToken() // consume ADMIN
	userName, err := p.parseQuotedString()
	if err != nil {
		return nil, err
	}

	cmd := NewCommand("revoke_admin")
	cmd.Params["user_name"] = userName

	p.nextToken()
	// Semicolon is optional for UNSET TOKEN
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return cmd, nil
}

func (p *Parser) parseRevokePermission() (*Command, error) {
	actions, err := p.parseIdentifierList()
	if err != nil {
		return nil, err
	}

	if p.curToken.Type != TokenOn {
		return nil, fmt.Errorf("expected ON")
	}
	p.nextToken()

	resource, err := p.parseIdentifier()
	if err != nil {
		return nil, err
	}

	p.nextToken()
	if p.curToken.Type != TokenFrom {
		return nil, fmt.Errorf("expected FROM")
	}
	p.nextToken()
	if p.curToken.Type != TokenRole {
		return nil, fmt.Errorf("expected ROLE")
	}
	p.nextToken()

	roleName, err := p.parseIdentifier()
	if err != nil {
		return nil, err
	}

	cmd := NewCommand("revoke_permission")
	cmd.Params["actions"] = actions
	cmd.Params["resource"] = resource
	cmd.Params["role_name"] = roleName

	p.nextToken()
	// Semicolon is optional for UNSET TOKEN
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return cmd, nil
}

func (p *Parser) parseIdentifierList() ([]string, error) {
	var list []string

	ident, err := p.parseIdentifier()
	if err != nil {
		return nil, err
	}
	list = append(list, ident)
	p.nextToken()

	for p.curToken.Type == TokenComma {
		p.nextToken()
		ident, err := p.parseIdentifier()
		if err != nil {
			return nil, err
		}
		list = append(list, ident)
		p.nextToken()
	}

	return list, nil
}

func (p *Parser) parseSetCommand() (*Command, error) {
	p.nextToken() // consume SET

	if p.curToken.Type == TokenVar {
		return p.parseSetVariable()
	}
	if p.curToken.Type == TokenDefault {
		return p.parseSetDefault()
	}
	if p.curToken.Type == TokenToken {
		return p.parseSetToken()
	}
	if p.curToken.Type == TokenMetadata {
		return p.parseSetMeta()
	}
	if p.curToken.Type == TokenLog {
		return p.parseSetLog()
	}

	return nil, fmt.Errorf("unknown SET target: %s", p.curToken.Value)
}

func (p *Parser) parseSetVariable() (*Command, error) {
	p.nextToken() // consume VAR
	varName, err := p.parseIdentifier()
	if err != nil {
		return nil, err
	}

	p.nextToken()
	varValue, err := p.parseVariableValue()
	if err != nil {
		return nil, err
	}

	cmd := NewCommand("set_variable")
	cmd.Params["var_name"] = varName
	cmd.Params["var_value"] = varValue

	p.nextToken()
	// Semicolon is optional for UNSET TOKEN
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return cmd, nil
}

func (p *Parser) parseSetDefault() (*Command, error) {
	p.nextToken() // consume DEFAULT

	var modelType, compositeModelName string
	var err error

	switch p.curToken.Type {
	case TokenChat:
		modelType = "chat"
	case TokenVision:
		modelType = "vision"
	case TokenEmbedding:
		modelType = "embedding"
	case TokenRerank:
		modelType = "rerank"
	case TokenASR:
		modelType = "asr"
	case TokenTTS:
		modelType = "tts"
	case TokenOCR:
		modelType = "ocr"
	default:
		return nil, fmt.Errorf("unknown model type: %s", p.curToken.Value)
	}
	p.nextToken() // pass model type

	if p.curToken.Type != TokenModel {
		return nil, fmt.Errorf("expected MODEL")
	}
	p.nextToken() // pass MODEL

	// Format: 'provider/instance/model' or just 'message'
	if p.curToken.Type != TokenQuotedString {
		return nil, fmt.Errorf("expected quoted string with format provider/instance/model")
	}

	compositeModelName, err = p.parseQuotedString()
	if err != nil {
		return nil, err
	}
	p.nextToken()

	cmd := NewCommand("set_default_model")
	cmd.Params["model_type"] = modelType
	cmd.Params["composite_model_name"] = compositeModelName

	p.nextToken()
	// Semicolon is optional for UNSET TOKEN
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return cmd, nil
}

func (p *Parser) parseSetToken() (*Command, error) {
	p.nextToken() // consume TOKEN

	tokenValue, err := p.parseQuotedString()
	if err != nil {
		return nil, err
	}

	cmd := NewCommand("set_token")
	cmd.Params["token"] = tokenValue

	p.nextToken()
	// Semicolon is optional for UNSET TOKEN
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return cmd, nil
}

func (p *Parser) parseSetLog() (*Command, error) {
	p.nextToken() // consume LOG

	switch p.curToken.Type {
	case TokenLevel:
		return p.parseSetLogLevel()
	default:
		return nil, fmt.Errorf("unknown log target: %s", p.curToken.Value)
	}
}

func (p *Parser) parseSetLogLevel() (*Command, error) {
	p.nextToken() // consume LEVEL

	cmd := NewCommand("set_log_level")
	switch p.curToken.Type {
	case TokenDebug:
		cmd.Params["level"] = "debug"
	case TokenInfo:
		cmd.Params["level"] = "info"
	case TokenWarn:
		cmd.Params["level"] = "warn"
	case TokenError:
		cmd.Params["level"] = "error"
	case TokenFatal:
		cmd.Params["level"] = "fatal"
	case TokenPanic:
		cmd.Params["level"] = "panic"
	default:
		return nil, fmt.Errorf("unknown log target: %s", p.curToken.Value)
	}
	p.nextToken()
	// Semicolon is optional for UNSET TOKEN
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return cmd, nil
}

func (p *Parser) parseResetCommand() (*Command, error) {
	p.nextToken() // consume RESET

	if p.curToken.Type != TokenDefault {
		return nil, fmt.Errorf("expected DEFAULT")
	}
	p.nextToken()

	var modelType string
	switch p.curToken.Type {
	case TokenChat:
		modelType = "chat"
	case TokenVision:
		modelType = "vision"
	case TokenEmbedding:
		modelType = "embedding"
	case TokenRerank:
		modelType = "rerank"
	case TokenASR:
		modelType = "asr"
	case TokenTTS:
		modelType = "tts"
	case TokenOCR:
		modelType = "ocr"
	default:
		return nil, fmt.Errorf("unknown model type: %s", p.curToken.Value)
	}

	cmd := NewCommand("reset_default_model")
	cmd.Params["model_type"] = modelType
	p.nextToken()

	if p.curToken.Type != TokenModel {
		return nil, fmt.Errorf("expected MODEL")
	}
	p.nextToken() // pass MODEL

	// Semicolon is optional for UNSET TOKEN
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return cmd, nil
}

func (p *Parser) parseGenerateCommand() (*Command, error) {
	p.nextToken() // consume GENERATE
	if p.curToken.Type != TokenToken {
		return nil, fmt.Errorf("expected TOKEN")
	}
	p.nextToken()
	if p.curToken.Type != TokenFor {
		return nil, fmt.Errorf("expected FOR")
	}
	p.nextToken()
	if p.curToken.Type != TokenUser {
		return nil, fmt.Errorf("expected USER")
	}
	p.nextToken()

	userName, err := p.parseQuotedString()
	if err != nil {
		return nil, err
	}

	cmd := NewCommand("generate_token")
	cmd.Params["user_name"] = userName

	p.nextToken()
	// Semicolon is optional
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return cmd, nil
}

func (p *Parser) parseImportCommand() (*Command, error) {
	p.nextToken() // consume IMPORT
	documentPaths, err := p.parseQuotedString()
	if err != nil {
		return nil, err
	}

	p.nextToken()
	if p.curToken.Type != TokenInto {
		return nil, fmt.Errorf("expected INTO")
	}
	p.nextToken()
	if p.curToken.Type != TokenDataset {
		return nil, fmt.Errorf("expected DATASET")
	}
	p.nextToken()

	datasetName, err := p.parseQuotedString()
	if err != nil {
		return nil, err
	}

	cmd := NewCommand("import_docs_into_dataset")
	cmd.Params["document_paths"] = documentPaths
	cmd.Params["dataset_name"] = datasetName

	p.nextToken()
	// Semicolon is optional for UNSET TOKEN
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return cmd, nil
}

// parseInsertCommand parses INSERT command and dispatches to specific handler
func (p *Parser) parseInsertCommand() (*Command, error) {
	p.nextToken() // consume INSERT

	// Expect CHUNKS or METADATA
	if p.curToken.Type == TokenChunks {
		return p.parseInsertChunksFromFile()
	}
	if p.curToken.Type == TokenMetadata {
		return p.parseInsertMetadataFromFile()
	}
	return nil, fmt.Errorf("expected CHUNKS or METADATA after INSERT, got %s", p.curToken.Value)
}

// Internal CLI for GO
// parseInsertChunksFromFile parses: INSERT CHUNKS FROM FILE "file_path"
func (p *Parser) parseInsertChunksFromFile() (*Command, error) {
	p.nextToken() // consume CHUNKS

	// Expect FROM
	if p.curToken.Type != TokenFrom {
		return nil, fmt.Errorf("expected FROM, got %s", p.curToken.Value)
	}
	p.nextToken()

	// Expect FILE
	if p.curToken.Type != TokenFile {
		return nil, fmt.Errorf("expected FILE, got %s", p.curToken.Value)
	}
	p.nextToken()

	// Get file path (quoted string)
	filePath, err := p.parseQuotedString()
	if err != nil {
		return nil, err
	}

	cmd := NewCommand("insert_chunks_from_file")
	cmd.Params["file_path"] = filePath

	p.nextToken()
	// Semicolon is optional
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return cmd, nil
}

// Internal CLI for GO
// parseInsertMetadataFromFile parses: INSERT METADATA FROM FILE "file_path"
func (p *Parser) parseInsertMetadataFromFile() (*Command, error) {
	p.nextToken() // consume METADATA

	// Expect FROM
	if p.curToken.Type != TokenFrom {
		return nil, fmt.Errorf("expected FROM, got %s", p.curToken.Value)
	}
	p.nextToken()

	// Expect FILE
	if p.curToken.Type != TokenFile {
		return nil, fmt.Errorf("expected FILE, got %s", p.curToken.Value)
	}
	p.nextToken()

	// Get file path (quoted string)
	filePath, err := p.parseQuotedString()
	if err != nil {
		return nil, err
	}

	cmd := NewCommand("insert_metadata_from_file")
	cmd.Params["file_path"] = filePath

	p.nextToken()
	// Semicolon is optional
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return cmd, nil
}

func (p *Parser) parseSearchCommand() (*Command, error) {
	p.nextToken() // consume SEARCH

	var err error
	var question string
	if p.curToken.Type == TokenQuotedString {
		question, err = p.parseQuotedString()
		if err != nil {
			return nil, err
		}
	} else if p.curToken.Type == TokenIdentifier {
		question, err = p.parseIdentifier()
		if err != nil {
			return nil, err
		}
	} else {
		return nil, fmt.Errorf("expected quoted string or identifier")
	}

	p.nextToken()

	if p.curToken.Type == TokenOn {
		p.nextToken() // skip on

		if p.curToken.Type != TokenDatasets {
			return nil, fmt.Errorf("expected DATASETS")
		}
		p.nextToken()

		datasets, err := p.parseQuotedString()
		if err != nil {
			return nil, err
		}

		cmd := NewCommand("search_on_datasets")
		cmd.Params["question"] = question
		cmd.Params["datasets"] = datasets

		p.nextToken()
		// Semicolon is optional for UNSET TOKEN
		if p.curToken.Type == TokenSemicolon {
			p.nextToken()
		}
		return cmd, nil
	}

	cmd := NewCommand("ce_search")

	cmd.Params["query"] = question

	if p.curToken.Type == TokenEOF {
		cmd.Params["path"] = "."
		return cmd, nil
	}

	for p.curToken.Type != TokenEOF {
		if p.curToken.Type == TokenDash {
			p.nextToken() // skip dash
			if p.curToken.Type != TokenIdentifier {
				return nil, fmt.Errorf("expect identifier")
			}

			if strings.ToLower(p.curToken.Value) == "n" {
				p.nextToken()
				var err error
				if p.curToken.Type != TokenInteger {
					return nil, fmt.Errorf("expect number")
				}
				cmd.Params["number"], err = p.parseNumber()
				if err != nil {
					return nil, err
				}
				p.nextToken()
				continue
			}

			//if strings.ToLower(p.curToken.Value) == "t" {
			//	p.nextToken()
			//	var err error
			//	if p.curToken.Type != TokenInteger {
			//		return nil, fmt.Errorf("expect number")
			//	}
			//	cmd.Params["threshold"], err = p.parseFloat()
			//	if err != nil {
			//		return nil, err
			//	}
			//	p.nextToken()
			//	continue
			//}

			return nil, fmt.Errorf("unknow parameter: %s", p.curToken.Value)
		} else if p.curToken.Type == TokenIdentifier {
			if cmd.Params["path"] == nil {
				cmd.Params["path"] = p.curToken.Value
			} else {
				cmd.Params["path"] = fmt.Sprintf("%s%s", cmd.Params["path"], p.curToken.Value)
			}
			p.nextToken() // skip path
			continue
		} else if p.curToken.Type == TokenSlash {
			if cmd.Params["path"] == nil {
				cmd.Params["path"] = "/"
			} else {
				cmd.Params["path"] = fmt.Sprintf("%s/", cmd.Params["path"])
			}
			p.nextToken() // skip slash
			if p.curToken.Type == TokenIdentifier {
				cmd.Params["path"] = fmt.Sprintf("%s%s", cmd.Params["path"], p.curToken.Value)
				p.nextToken()
			}
			continue
		}
	}
	return cmd, nil
}

func (p *Parser) parseListModelsOfProvider() (*Command, error) {

	if p.curToken.Type == TokenSupported {
		// List supported models
		p.nextToken()

		cmd := NewCommand("list_supported_models")
		if p.curToken.Type != TokenModels {
			return nil, fmt.Errorf("expected MODELS")
		}
		p.nextToken()

		if p.curToken.Type != TokenFrom {
			return nil, fmt.Errorf("expected FROM")
		}
		p.nextToken()

		if p.curToken.Type != TokenQuotedString {
			return nil, fmt.Errorf("expected quoted string for provider name")
		}
		firstName, err := p.parseQuotedString()
		if err != nil {
			return nil, err
		}
		p.nextToken()

		if p.curToken.Type != TokenQuotedString {
			return nil, fmt.Errorf("expected quoted string for instance name")
		}
		secondName, err := p.parseQuotedString()
		if err != nil {
			return nil, err
		}
		p.nextToken()

		cmd.Params["provider_name"] = firstName
		cmd.Params["instance_name"] = secondName

		// Semicolon is optional for UNSET TOKEN
		if p.curToken.Type == TokenSemicolon {
			p.nextToken()
		}
		return cmd, nil
	}

	if p.curToken.Type != TokenModels {
		return nil, fmt.Errorf("expected MODELS")
	}
	p.nextToken()

	if p.curToken.Type != TokenFrom {
		return nil, fmt.Errorf("expected FROM")
	}
	p.nextToken()

	// Parse first quoted string (could be instance_name or provider_name)
	firstName, err := p.parseQuotedString()
	if err != nil {
		return nil, err
	}
	p.nextToken()

	// Check if there's a second quoted string (provider_name)
	// If so, format is: LIST MODELS FROM <instance_name> <provider_name>
	// If not, format is: LIST MODELS FROM <provider_name>
	if p.curToken.Type == TokenQuotedString {
		// Two arguments: instance_name and provider_name
		instanceName, err := p.parseQuotedString()
		if err != nil {
			return nil, err
		}
		cmd := NewCommand("list_instance_models")
		cmd.Params["instance_name"] = instanceName
		cmd.Params["provider_name"] = firstName
		p.nextToken()
		// Semicolon is optional for UNSET TOKEN
		if p.curToken.Type == TokenSemicolon {
			p.nextToken()
		}
		return cmd, nil
	}

	// Only one argument: provider_name
	cmd := NewCommand("list_provider_models")
	cmd.Params["provider_name"] = firstName
	// Semicolon is optional for UNSET TOKEN
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return cmd, nil
}

func (p *Parser) parseEnableCommand() (*Command, error) {
	p.nextToken() // consume ENABLE

	if p.curToken.Type != TokenModel {
		return nil, fmt.Errorf("expected MODEL")
	}
	p.nextToken()

	modelName, err := p.parseQuotedString()
	if err != nil {
		return nil, err
	}
	p.nextToken()

	if p.curToken.Type != TokenFrom {
		return nil, fmt.Errorf("expected FROM")
	}
	p.nextToken()

	modelProvider, err := p.parseQuotedString()
	if err != nil {
		return nil, err
	}
	p.nextToken()

	modelInstance, err := p.parseQuotedString()
	if err != nil {
		return nil, err
	}
	p.nextToken()

	// Semicolon is optional for UNSET TOKEN
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}

	cmd := NewCommand("enable_model")
	cmd.Params["model_name"] = modelName
	cmd.Params["instance_name"] = modelInstance
	cmd.Params["provider_name"] = modelProvider
	return cmd, nil
}

func (p *Parser) parseDisableCommand() (*Command, error) {
	p.nextToken() // consume DISABLE

	if p.curToken.Type != TokenModel {
		return nil, fmt.Errorf("expected MODEL")
	}
	p.nextToken()

	modelName, err := p.parseQuotedString()
	if err != nil {
		return nil, err
	}
	p.nextToken()

	if p.curToken.Type != TokenFrom {
		return nil, fmt.Errorf("expected FROM")
	}
	p.nextToken()

	modelProvider, err := p.parseQuotedString()
	if err != nil {
		return nil, err
	}
	p.nextToken()

	modelInstance, err := p.parseQuotedString()
	if err != nil {
		return nil, err
	}
	p.nextToken()

	// Semicolon is optional for UNSET TOKEN
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}

	cmd := NewCommand("disable_model")
	cmd.Params["model_name"] = modelName
	cmd.Params["instance_name"] = modelInstance
	cmd.Params["provider_name"] = modelProvider
	return cmd, nil
}

// CHAT 'model@instance@provider' 'hello world'
// CHAT WITH 'model@instance@provider' MESSAGE 'hello world' 'who are you' IMAGE 'url1' 'file0' VIDEO "url2.mov" "file1" FILE "url" "path file2" AUDIO "file.wav"
func (p *Parser) parseChatCommand() (*Command, error) {
	p.nextToken() // consume CHAT

	var err error
	var compositeModelName string = ""
	var messages []string
	var images []string
	var videos []string
	var audios []string
	var files []string
	effort := "default"
	verbosity := "low"

optionsLoop:
	for {
		switch p.curToken.Type {
		case TokenWith:
			p.nextToken()
			// 'model@instance@provider'
			if compositeModelName != "" {
				return nil, fmt.Errorf("model name is already set")
			}
			compositeModelName, err = p.parseQuotedString()
			if err != nil {
				return nil, err
			}
			p.nextToken()
		case TokenMessage:
			p.nextToken()
			if len(messages) != 0 {
				return nil, fmt.Errorf("message is already set")
			}
		messageLoop:
			for {
				if p.curToken.Type != TokenQuotedString {
					break messageLoop
				}
				var message string
				message, err = p.parseQuotedString()
				if err != nil {
					return nil, err
				}
				message = strings.TrimSpace(message)
				messages = append(messages, message)
				p.nextToken()
			}
		case TokenImage:
			p.nextToken()
			if len(images) != 0 {
				return nil, fmt.Errorf("image is already set")
			}
		imageLoop:
			for {
				if p.curToken.Type != TokenQuotedString {
					break imageLoop
				}
				var image string
				image, err = p.parseQuotedString()
				if err != nil {
					return nil, err
				}
				images = append(images, image)
				p.nextToken()
			}
		case TokenVideo:
			p.nextToken()
			if len(videos) != 0 {
				return nil, fmt.Errorf("video is already set")
			}
		videoLoop:
			for {
				if p.curToken.Type != TokenQuotedString {
					break videoLoop
				}
				var video string
				video, err = p.parseQuotedString()
				if err != nil {
					return nil, err
				}
				videos = append(videos, video)
				p.nextToken()
			}
		case TokenAudio:
			p.nextToken()
			if len(audios) != 0 {
				return nil, fmt.Errorf("video is already set")
			}
		audioLoop:
			for {
				if p.curToken.Type != TokenQuotedString {
					break audioLoop
				}
				var audio string
				audio, err = p.parseQuotedString()
				if err != nil {
					return nil, err
				}
				audios = append(audios, audio)
				p.nextToken()
			}
		case TokenFile:
			p.nextToken()
			if len(files) != 0 {
				return nil, fmt.Errorf("video is already set")
			}
		fileLoop:
			for {
				if p.curToken.Type != TokenQuotedString {
					break fileLoop
				}
				var file string
				file, err = p.parseQuotedString()
				if err != nil {
					return nil, err
				}
				files = append(files, file)
				p.nextToken()
			}
		case TokenEffort:
			p.nextToken() // pass Effort
			switch p.curToken.Type {
			case TokenNone:
				effort = "none"
			case TokenMinimal:
				effort = "minimal"
			case TokenLow:
				effort = "low"
			case TokenMedium:
				effort = "medium"
			case TokenHigh:
				effort = "high"
			case TokenMax:
				effort = "max"
			default:
				return nil, fmt.Errorf("invalid effort level")
			}
			p.nextToken()
			break optionsLoop
		case TokenVerbosity:
			p.nextToken() // pass VERBOSITY
			switch p.curToken.Type {
			case TokenLow:
				verbosity = "low"
			case TokenMedium:
				verbosity = "median"
			case TokenHigh:
				verbosity = "high"
			default:
				return nil, fmt.Errorf("invalid verbosity level")
			}
			p.nextToken()
			break optionsLoop
		case TokenSemicolon:
			p.nextToken()
			break optionsLoop // done
		default:
			// No more options to process
			break optionsLoop
		}
	}
	cmd := NewCommand("chat_to_model")

	cmd.Params["composite_model_name"] = compositeModelName
	cmd.Params["messages"] = messages
	cmd.Params["images"] = images
	cmd.Params["videos"] = videos
	cmd.Params["audios"] = audios
	cmd.Params["files"] = files
	cmd.Params["thinking"] = false
	cmd.Params["stream"] = false
	cmd.Params["effort"] = effort
	cmd.Params["verbosity"] = verbosity
	return cmd, nil
}

func (p *Parser) parseThinkCommand() (*Command, error) {

	p.nextToken() // consume THINK

	if p.curToken.Type != TokenChat {
		return nil, fmt.Errorf("expected CHAT after THINK")
	}

	command, err := p.parseChatCommand()
	if err != nil {
		return nil, err
	}
	command.Params["thinking"] = true
	return command, nil
}

func (p *Parser) parseStreamCommand() (*Command, error) {

	p.nextToken() // consume STREAM

	var command *Command
	var err error

	switch p.curToken.Type {
	case TokenChat:
		command, err = p.parseChatCommand()
		if err != nil {
			return nil, err
		}
	case TokenThink:
		command, err = p.parseThinkCommand()
		if err != nil {
			return nil, err
		}
	case TokenASR:
		command, err = p.parseASRCommand()
		if err != nil {
			return nil, err
		}
	case TokenTTS:
		command, err = p.parseTTSCommand()
		if err != nil {
			return nil, err
		}
	default:
		return nil, fmt.Errorf("expected CHAT, THINK, ASR, or TTS after STREAM")
	}

	command.Params["stream"] = true
	return command, nil
}

func (p *Parser) parseEmbedCommand() (*Command, error) {
	p.nextToken() // consume EMBED

	if p.curToken.Type != TokenText {
		return nil, fmt.Errorf("expected WITH after EMBED")
	}
	p.nextToken() // consume TEXT

	var texts []string

textLoop:
	for {
		if p.curToken.Type != TokenQuotedString {
			break textLoop
		}
		text, err := p.parseQuotedString()
		if err != nil {
			return nil, err
		}
		text = strings.TrimSpace(text)
		texts = append(texts, text)
		p.nextToken()
	}

	if p.curToken.Type != TokenWith {
		return nil, fmt.Errorf("expected WITH after EMBED")
	}
	p.nextToken() // consume WITH

	compositeModelName, err := p.parseQuotedString()
	if err != nil {
		return nil, err
	}
	p.nextToken()

	if p.curToken.Type != TokenDimension {
		return nil, fmt.Errorf("expected DIMENSION")
	}
	p.nextToken() // consume WITH

	dimension, err := p.parseNumber()
	if err != nil {
		return nil, err
	}
	p.nextToken()

	cmd := NewCommand("embed_user_text")
	cmd.Params["composite_model_name"] = compositeModelName
	cmd.Params["texts"] = texts
	cmd.Params["dimension"] = dimension
	return cmd, nil
}

func (p *Parser) parseRerankCommand() (*Command, error) {
	p.nextToken() // consume RERANK

	if p.curToken.Type != TokenQuery {
		return nil, fmt.Errorf("expected WITH after EMBED")
	}
	p.nextToken() // consume QUERY

	query, err := p.parseQuotedString()
	if err != nil {
		return nil, err
	}
	query = strings.TrimSpace(query)
	p.nextToken() // consume query

	if p.curToken.Type != TokenDocument {
		return nil, fmt.Errorf("expected DOCUMENT after query")
	}
	p.nextToken() // consume DOCUMENT

	var documents []string

documentLoop:
	for {
		if p.curToken.Type != TokenQuotedString {
			break documentLoop
		}
		var document string
		document, err = p.parseQuotedString()
		if err != nil {
			return nil, err
		}
		document = strings.TrimSpace(document)
		documents = append(documents, document)
		p.nextToken()
	}

	if p.curToken.Type != TokenWith {
		return nil, fmt.Errorf("expected WITH after EMBED")
	}
	p.nextToken() // consume WITH

	compositeModelName, err := p.parseQuotedString()
	if err != nil {
		return nil, err
	}
	p.nextToken()

	if p.curToken.Type != TokenTop {
		return nil, fmt.Errorf("expected TOP after model")
	}
	p.nextToken()

	topN, err := p.parseNumber()
	if err != nil {
		return nil, err
	}
	p.nextToken()

	cmd := NewCommand("rarank_user_document")
	cmd.Params["composite_model_name"] = compositeModelName
	cmd.Params["query"] = query
	cmd.Params["documents"] = documents
	cmd.Params["top_n"] = topN
	return cmd, nil
}

func (p *Parser) parseASRCommand() (*Command, error) {
	p.nextToken() // consume ASR

	if p.curToken.Type != TokenWith {
		return nil, fmt.Errorf("expected WITH after ASR")
	}
	p.nextToken() // consume WITH

	compositeModelName, err := p.parseQuotedString()
	if err != nil {
		return nil, err
	}
	p.nextToken()

	if p.curToken.Type != TokenAudio {
		return nil, fmt.Errorf("expected AUDIO to ASR")
	}
	p.nextToken() // consume AUDIO

	audioFile, err := p.parseQuotedString()
	if err != nil {
		return nil, err
	}
	p.nextToken()

	cmd := NewCommand("asr_user_command")
	cmd.Params["composite_model_name"] = compositeModelName
	cmd.Params["audio_file"] = audioFile

	for p.curToken.Type != TokenEOF && p.curToken.Type != TokenSemicolon {
		switch p.curToken.Type {
		case TokenParam:
			p.nextToken()
			if p.curToken.Type != TokenQuotedString {
				return nil, fmt.Errorf("expect quoted string after 'param'")
			}
			cmd.Params["param_str"] = strings.Trim(p.curToken.Value, "\"'")
			p.nextToken()
		default:
			return nil, fmt.Errorf("unexpected token in asr command: %s", p.curToken.Value)
		}
	}

	// Semicolon is optional for UNSET TOKEN
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}

	return cmd, nil
}

func (p *Parser) parseTTSCommand() (*Command, error) {
	p.nextToken()

	cmd := NewCommand("tts_user_command")

	if p.curToken.Type != TokenWith {
		return nil, fmt.Errorf("expect 'with' after tts")
	}
	p.nextToken()

	if p.curToken.Type != TokenQuotedString && p.curToken.Type != TokenIdentifier {
		return nil, fmt.Errorf("expect model name after 'with'")
	}
	cmd.Params["composite_model_name"] = strings.Trim(p.curToken.Value, "\"'")
	p.nextToken()

	if p.curToken.Type != TokenText {
		return nil, fmt.Errorf("expect 'text' parameter")
	}
	p.nextToken()

	if p.curToken.Type != TokenQuotedString {
		return nil, fmt.Errorf("expect quoted string after 'text'")
	}
	cmd.Params["text"] = strings.Trim(p.curToken.Value, "\"'")
	p.nextToken()

	for p.curToken.Type != TokenEOF && p.curToken.Type != TokenSemicolon {
		switch p.curToken.Type {
		case TokenPlay:
			p.nextToken()
			cmd.Params["play"] = true
		case TokenParam:
			p.nextToken()
			if p.curToken.Type != TokenQuotedString {
				return nil, fmt.Errorf("expect quoted string after 'param'")
			}
			cmd.Params["param_str"] = strings.Trim(p.curToken.Value, "\"'")
			p.nextToken()
			p.nextToken()
		case TokenSave:
			p.nextToken()

			if p.curToken.Type != TokenQuotedString && p.curToken.Type != TokenIdentifier {
				return nil, fmt.Errorf("expect directory path after 'save'")
			}

			cmd.Params["save"] = true
			cmd.Params["save_path"] = strings.Trim(p.curToken.Value, "\"'")
			p.nextToken()
		case TokenFormat:
			p.nextToken()
			if p.curToken.Type != TokenQuotedString && p.curToken.Type != TokenIdentifier {
				return nil, fmt.Errorf("expect format string (e.g. 'wav') after 'format'")
			}
			cmd.Params["format"] = strings.Trim(p.curToken.Value, "\"'")
			p.nextToken()
		default:
			return nil, fmt.Errorf("unexpected token: %s", p.curToken.Value)
		}
	}

	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}

	return cmd, nil
}

func (p *Parser) parseOCRCommand() (*Command, error) {
	p.nextToken() // consume OCR

	if p.curToken.Type != TokenWith {
		return nil, fmt.Errorf("expected WITH after OCR")
	}
	p.nextToken() // consume WITH

	compositeModelName, err := p.parseQuotedString()
	if err != nil {
		return nil, err
	}
	p.nextToken()

	cmd := NewCommand("ocr_user_command")

	switch p.curToken.Type {
	case TokenFile:
		p.nextToken()
		var file string
		file, err = p.parseQuotedString()
		if err != nil {
			return nil, err
		}
		cmd.Params["file"] = file
		p.nextToken()
	case TokenURL:
		p.nextToken()
		var url string
		url, err = p.parseQuotedString()
		if err != nil {
			return nil, err
		}
		cmd.Params["url"] = url
		p.nextToken()
	default:
		return nil, fmt.Errorf("expected FILE or URL")
	}

	cmd.Params["composite_model_name"] = compositeModelName

	return cmd, nil
}

func (p *Parser) parseModelParseCommand() (*Command, error) {
	p.nextToken() // consume WITH

	compositeModelName, err := p.parseQuotedString()
	if err != nil {
		return nil, err
	}
	p.nextToken()

	cmd := NewCommand("parse_file_user_command")

	switch p.curToken.Type {
	case TokenFile:
		p.nextToken()
		var file string
		file, err = p.parseQuotedString()
		if err != nil {
			return nil, err
		}
		cmd.Params["file"] = file
		p.nextToken()
	case TokenURL:
		p.nextToken()
		var url string
		url, err = p.parseQuotedString()
		if err != nil {
			return nil, err
		}
		cmd.Params["url"] = url
		p.nextToken()
	default:
		return nil, fmt.Errorf("expected FILE or URL")
	}

	cmd.Params["composite_model_name"] = compositeModelName

	return cmd, nil
}

func (p *Parser) parseCheckCommand() (*Command, error) {
	p.nextToken() // consume CHECK

	if p.curToken.Type != TokenInstance {
		return nil, fmt.Errorf("expected INSTANCE after CHECK")
	}
	p.nextToken()

	if p.curToken.Type != TokenQuotedString {
		return nil, fmt.Errorf("expected instance name after INSTANCE")
	}
	instanceName := p.curToken.Value
	p.nextToken()

	if p.curToken.Type != TokenFrom {
		return nil, fmt.Errorf("expected FROM after instance name")
	}
	p.nextToken()

	if p.curToken.Type != TokenQuotedString {
		return nil, fmt.Errorf("expected provider name after FROM")
	}
	providerName := p.curToken.Value
	p.nextToken()

	// Semicolon is optional
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}

	cmd := NewCommand("check_provider_connection")
	cmd.Params["provider_name"] = providerName
	cmd.Params["instance_name"] = instanceName
	return cmd, nil
}

func (p *Parser) parseUseCommand() (*Command, error) {
	p.nextToken() // consume USE

	if p.curToken.Type != TokenModel {
		return nil, fmt.Errorf("expected MODEL after USE")
	}
	p.nextToken() // consume MODEL

	// Parse model identifier in format 'model@instance@provider'
	compositeModelName, err := p.parseQuotedString()
	if err != nil {
		return nil, fmt.Errorf("expected model identifier in format 'model@instance@provider': %w", err)
	}
	p.nextToken()

	// Semicolon is optional
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}

	cmd := NewCommand("use_model")
	cmd.Params["composite_model_name"] = compositeModelName
	return cmd, nil
}

func (p *Parser) parseParseCommand() (*Command, error) {
	p.nextToken() // consume PARSE

	switch p.curToken.Type {
	case TokenDataset:
		return p.parseParseDataset()
	case TokenWith:
		return p.parseModelParseCommand()
	case TokenDocument:
		return p.parseParseDocs()
	default:
		return nil, fmt.Errorf("expected DATASET, WITH, or DOCUMENT")
	}
}

func (p *Parser) parseParseDataset() (*Command, error) {
	p.nextToken() // consume DATASET
	datasetName, err := p.parseQuotedString()
	if err != nil {
		return nil, err
	}

	p.nextToken()
	var method string
	if p.curToken.Type == TokenSync {
		method = "sync"
	} else if p.curToken.Type == TokenAsync {
		method = "async"
	} else {
		return nil, fmt.Errorf("expected SYNC or ASYNC")
	}

	cmd := NewCommand("parse_dataset")
	cmd.Params["dataset_name"] = datasetName
	cmd.Params["method"] = method

	p.nextToken()
	// Semicolon is optional for UNSET TOKEN
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return cmd, nil
}

func (p *Parser) parseParseDocs() (*Command, error) {
	p.nextToken() // consume document

	documentsStr, err := p.parseQuotedString()
	if err != nil {
		return nil, err
	}

	p.nextToken()
	if p.curToken.Type != TokenFrom {
		return nil, fmt.Errorf("expected FROM")
	}
	p.nextToken()

	datasetID, err := p.parseQuotedString()
	if err != nil {
		return nil, err
	}
	p.nextToken()

	cmd := NewCommand("parse_documents_user_command")

	documents := strings.Split(documentsStr, " ")

	cmd.Params["documents"] = documents
	cmd.Params["dataset_id"] = datasetID

	// Semicolon is optional for UNSET TOKEN
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return cmd, nil
}

func (p *Parser) parseBenchmarkCommand() (*Command, error) {
	cmd := NewCommand("benchmark")

	p.nextToken() // consume BENCHMARK
	concurrency, err := p.parseNumber()
	if err != nil {
		return nil, err
	}
	cmd.Params["concurrency"] = concurrency

	p.nextToken()
	iterations, err := p.parseNumber()
	if err != nil {
		return nil, err
	}
	cmd.Params["iterations"] = iterations

	p.nextToken()
	// Parse user_statement
	nestedCmd, err := p.parseUserStatement() // Not only user statement
	if err != nil {
		return nil, err
	}
	cmd.Params["command"] = nestedCmd

	return cmd, nil
}

func (p *Parser) parseUserStatement() (*Command, error) {
	switch p.curToken.Type {
	case TokenPing:
		return p.parsePingServer()
	case TokenDelete:
		return p.parseDeleteCommand()
	case TokenShow:
		return p.parseShowCommand()
	case TokenCreate:
		return p.parseCreateCommand()
	case TokenDrop:
		return p.parseDropCommand()
	case TokenSet:
		return p.parseSetCommand()
	case TokenUnset:
		return p.parseUnsetCommand()
	case TokenReset:
		return p.parseResetCommand()
	case TokenList:
		return p.parseListCommand()
	case TokenParse:
		return p.parseParseCommand()
	case TokenImport:
		return p.parseImportCommand()
	case TokenInsert:
		return p.parseInsertCommand()
	case TokenSearch:
		return p.parseSearchCommand()
	case TokenGet:
		return p.parseGetCommand()
	case TokenUpdate:
		return p.parseUpdateCommand()
	case TokenRemove:
		return p.parseRemoveCommand()
	default:
		return nil, fmt.Errorf("invalid user statement: %s", p.curToken.Value)
	}
}

func (p *Parser) parseStartupCommand() (*Command, error) {
	p.nextToken() // consume STARTUP
	if p.curToken.Type != TokenService {
		return nil, fmt.Errorf("expected SERVICE")
	}
	p.nextToken()

	serviceNum, err := p.parseNumber()
	if err != nil {
		return nil, err
	}

	cmd := NewCommand("startup_service")
	cmd.Params["number"] = serviceNum

	p.nextToken()
	// Semicolon is optional for UNSET TOKEN
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return cmd, nil
}

func (p *Parser) parseShutdownCommand() (*Command, error) {
	p.nextToken() // consume SHUTDOWN
	if p.curToken.Type != TokenService {
		return nil, fmt.Errorf("expected SERVICE")
	}
	p.nextToken()

	serviceNum, err := p.parseNumber()
	if err != nil {
		return nil, err
	}

	cmd := NewCommand("shutdown_service")
	cmd.Params["number"] = serviceNum

	p.nextToken()
	// Semicolon is optional for UNSET TOKEN
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return cmd, nil
}

func (p *Parser) parseRestartCommand() (*Command, error) {
	p.nextToken() // consume RESTART
	if p.curToken.Type != TokenService {
		return nil, fmt.Errorf("expected SERVICE")
	}
	p.nextToken()

	serviceNum, err := p.parseNumber()
	if err != nil {
		return nil, err
	}

	cmd := NewCommand("restart_service")
	cmd.Params["number"] = serviceNum

	p.nextToken()
	// Semicolon is optional for UNSET TOKEN
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return cmd, nil
}

func (p *Parser) parseUnsetCommand() (*Command, error) {
	p.nextToken() // consume UNSET

	if p.curToken.Type != TokenToken {
		return nil, fmt.Errorf("expected TOKEN after UNSET")
	}
	p.nextToken()

	// Semicolon is optional for UNSET TOKEN
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}
	return NewCommand("unset_token"), nil
}

// parseGetCommand parses: GET CHUNK 'chunk_id'
func (p *Parser) parseGetCommand() (*Command, error) {
	p.nextToken() // consume GET

	if p.curToken.Type == TokenChunk {
		return p.parseGetChunk()
	}

	return nil, fmt.Errorf("unknown GET target: %s", p.curToken.Value)
}

// parseGetChunk parses: GET CHUNK 'chunk_id' OF DOCUMENT 'doc_id' IN DATASET 'dataset_id'
func (p *Parser) parseGetChunk() (*Command, error) {
	p.nextToken() // consume CHUNK

	// Parse chunk_id
	chunkID, err := p.parseQuotedString()
	if err != nil {
		return nil, fmt.Errorf("expected chunk_id: %w", err)
	}

	cmd := NewCommand("get_chunk")
	cmd.Params["chunk_id"] = chunkID

	p.nextToken()
	if p.curToken.Type != TokenOf {
		return nil, fmt.Errorf("expected OF after chunk_id")
	}
	p.nextToken()

	if p.curToken.Type != TokenDocument {
		return nil, fmt.Errorf("expected DOCUMENT after OF")
	}
	p.nextToken()

	// Parse doc_id
	docID, err := p.parseQuotedString()
	if err != nil {
		return nil, fmt.Errorf("expected doc_id: %w", err)
	}
	cmd.Params["doc_id"] = docID

	p.nextToken()
	if p.curToken.Type != TokenIn {
		return nil, fmt.Errorf("expected IN after doc_id")
	}
	p.nextToken()

	if p.curToken.Type != TokenDataset {
		return nil, fmt.Errorf("expected DATASET after IN")
	}
	p.nextToken()

	// Parse dataset_id
	datasetID, err := p.parseQuotedString()
	if err != nil {
		return nil, fmt.Errorf("expected dataset_id: %w", err)
	}
	cmd.Params["dataset_id"] = datasetID

	p.nextToken()
	// Semicolon is optional
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}

	return cmd, nil
}

// Internal
// parseUpdateCommand parses: UPDATE CHUNK 'chunk_id' OF DATASET 'dataset_name' SET '{"content": "..."}'
func (p *Parser) parseUpdateCommand() (*Command, error) {
	p.nextToken() // consume UPDATE

	if p.curToken.Type == TokenChunk {
		return p.parseUpdateChunk()
	}

	return nil, fmt.Errorf("unknown UPDATE target: %s", p.curToken.Value)
}

// Internal CLI for GO
// parseUpdateChunk parses: UPDATE CHUNK 'chunk_id' OF DOCUMENT 'doc_id' IN DATASET 'dataset_id' SET '{"content": "..."}'
func (p *Parser) parseUpdateChunk() (*Command, error) {
	p.nextToken() // consume CHUNK

	// Parse chunk_id
	chunkID, err := p.parseQuotedString()
	if err != nil {
		return nil, fmt.Errorf("expected chunk_id: %w", err)
	}

	cmd := NewCommand("update_chunk")
	cmd.Params["chunk_id"] = chunkID

	p.nextToken()
	if p.curToken.Type != TokenOf {
		return nil, fmt.Errorf("expected OF after chunk_id")
	}
	p.nextToken()

	if p.curToken.Type != TokenDocument {
		return nil, fmt.Errorf("expected DOCUMENT after OF")
	}
	p.nextToken()

	// Parse doc_id
	docID, err := p.parseQuotedString()
	if err != nil {
		return nil, fmt.Errorf("expected doc_id: %w", err)
	}
	cmd.Params["doc_id"] = docID

	p.nextToken()
	if p.curToken.Type != TokenIn {
		return nil, fmt.Errorf("expected IN after doc_id")
	}
	p.nextToken()

	if p.curToken.Type != TokenDataset {
		return nil, fmt.Errorf("expected DATASET after IN")
	}
	p.nextToken()

	// Parse dataset_name
	datasetName, err := p.parseQuotedString()
	if err != nil {
		return nil, fmt.Errorf("expected dataset_name: %w", err)
	}
	cmd.Params["dataset_name"] = datasetName

	p.nextToken()
	if p.curToken.Type != TokenSet {
		return nil, fmt.Errorf("expected SET after dataset_name")
	}
	p.nextToken()

	// Parse JSON body
	jsonBody, err := p.parseQuotedString()
	if err != nil {
		return nil, fmt.Errorf("expected JSON body: %w", err)
	}
	cmd.Params["json_body"] = jsonBody

	p.nextToken()
	// Semicolon is optional
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}

	return cmd, nil
}

// parseSetMeta parses: SET METADATA OF DOCUMENT 'doc_id' TO '{"key": "value"}'
func (p *Parser) parseSetMeta() (*Command, error) {
	p.nextToken() // consume METADATA

	// Expect OF
	if p.curToken.Type != TokenOf {
		return nil, fmt.Errorf("expected OF after SET METADATA")
	}
	p.nextToken()

	// Expect DOCUMENT
	if p.curToken.Type != TokenDocument {
		return nil, fmt.Errorf("expected DOCUMENT after SET METADATA OF")
	}
	p.nextToken()

	// Parse doc_id
	docID, err := p.parseQuotedString()
	if err != nil {
		return nil, fmt.Errorf("expected doc_id: %w", err)
	}
	cmd := NewCommand("set_meta")
	cmd.Params["doc_id"] = docID

	p.nextToken()
	// Expect TO
	if p.curToken.Type != TokenTo {
		return nil, fmt.Errorf("expected TO after doc_id")
	}
	p.nextToken()

	// Parse meta JSON
	meta, err := p.parseQuotedString()
	if err != nil {
		return nil, fmt.Errorf("expected meta JSON: %w", err)
	}
	cmd.Params["meta"] = meta

	p.nextToken()
	// Semicolon is optional
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}

	return cmd, nil
}

// parseDeleteMeta parses: DELETE METADATA OF DOCUMENT 'doc_id' [KEYS '["key1", "key2"]']
// If KEYS is not provided, deletes entire document metadata
func (p *Parser) parseDeleteMeta() (*Command, error) {
	p.nextToken() // consume METADATA

	// Expect OF
	if p.curToken.Type != TokenOf {
		return nil, fmt.Errorf("expected OF after DELETE METADATA")
	}
	p.nextToken()

	// Expect DOCUMENT
	if p.curToken.Type != TokenDocument {
		return nil, fmt.Errorf("expected DOCUMENT after DELETE METADATA OF")
	}
	p.nextToken()

	// Parse doc_id
	docID, err := p.parseQuotedString()
	if err != nil {
		return nil, fmt.Errorf("expected doc_id: %w", err)
	}
	cmd := NewCommand("delete_meta")
	cmd.Params["doc_id"] = docID

	p.nextToken()
	// KEYS is optional - if not provided, delete entire document metadata
	if p.curToken.Type != TokenKeys {
		if p.curToken.Type == TokenSemicolon {
			p.nextToken()
			return cmd, nil
		}
		if p.curToken.Type == TokenEOF {
			return cmd, nil
		}
		return nil, fmt.Errorf("expected KEYS or end of command after doc_id")
	}

	// Parse keys JSON array
	p.nextToken()
	keys, err := p.parseQuotedString()
	if err != nil {
		return nil, fmt.Errorf("expected keys JSON array: %w", err)
	}
	cmd.Params["keys"] = keys

	p.nextToken()
	// Semicolon is optional
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
		return cmd, nil
	}
	if p.curToken.Type != TokenEOF {
		return nil, fmt.Errorf("expected end of command after KEYS")
	}

	return cmd, nil
}

// parseRemoveTags parses: REMOVE TAGS 'tag1', 'tag2' from DATASET 'dataset_name';
func (p *Parser) parseRemoveTags() (*Command, error) {
	p.nextToken() // consume TAGS

	// Parse first tag
	tag, err := p.parseQuotedString()
	if err != nil {
		return nil, fmt.Errorf("expected tag: %w", err)
	}
	tags := []string{tag}

	// Parse additional tags separated by commas
	for {
		p.nextToken()
		if p.curToken.Type == TokenComma {
			p.nextToken()
			tag, err := p.parseQuotedString()
			if err != nil {
				return nil, fmt.Errorf("expected tag after comma: %w", err)
			}
			tags = append(tags, tag)
		} else {
			break
		}
	}
	cmd := NewCommand("rm_tags")
	cmd.Params["tags"] = tags

	// Expect from
	if p.curToken.Type != TokenFrom {
		return nil, fmt.Errorf("expected FROM after tags")
	}
	p.nextToken()

	// Expect DATASET
	if p.curToken.Type != TokenDataset {
		return nil, fmt.Errorf("expected DATASET after FROM")
	}
	p.nextToken()

	// Parse dataset_name
	datasetName, err := p.parseQuotedString()
	if err != nil {
		return nil, fmt.Errorf("expected dataset_name: %w", err)
	}
	cmd.Params["dataset_name"] = datasetName

	// Semicolon is optional
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}

	return cmd, nil
}

// parseRemoveChunk parses:
//   - REMOVE CHUNKS 'chunk_id1', 'chunk_id2' FROM DOCUMENT 'doc_id' IN DATASET 'dataset_name';
//   - REMOVE ALL CHUNKS FROM DOCUMENT 'doc_id' IN DATASET 'dataset_name';
func (p *Parser) parseRemoveChunk() (*Command, error) {
	cmd := NewCommand("remove_chunks")

	// Check if ALL CHUNKS - if we came here from TokenAll case, curToken is already ALL
	if p.curToken.Type == TokenAll {
		p.nextToken() // consume ALL
		if p.curToken.Type != TokenChunks {
			return nil, fmt.Errorf("expected CHUNKS after ALL")
		}
		p.nextToken() // consume CHUNKS
		cmd.Params["delete_all"] = true
	} else {
		// curToken is TokenChunks, consume it first
		p.nextToken()
		// Multiple chunks: REMOVE CHUNKS 'id1' 'id2' FROM DOCUMENT 'doc_id' IN DATASET 'dataset_name' (space-separated)
		// Parse first chunk ID
		chunkID, err := p.parseQuotedString()
		if err != nil {
			return nil, fmt.Errorf("expected chunk_id: %w", err)
		}
		chunkIDs := []string{chunkID}

		// Parse additional chunk IDs separated by spaces (each quoted)
		for {
			p.nextToken()
			// Stop if we hit FROM or non-quoted token
			if p.curToken.Type == TokenFrom || p.curToken.Type != TokenQuotedString {
				break
			}
			chunkID, err := p.parseQuotedString()
			if err != nil {
				return nil, fmt.Errorf("expected chunk_id: %w", err)
			}
			chunkIDs = append(chunkIDs, chunkID)
		}
		cmd.Params["chunk_ids"] = chunkIDs
	}

	// Expect FROM
	if p.curToken.Type != TokenFrom {
		return nil, fmt.Errorf("expected FROM after chunk(s)")
	}
	p.nextToken()

	// Expect DOCUMENT
	if p.curToken.Type != TokenDocument {
		return nil, fmt.Errorf("expected DOCUMENT after FROM")
	}
	p.nextToken()

	// Parse doc_id
	docID, err := p.parseQuotedString()
	if err != nil {
		return nil, fmt.Errorf("expected doc_id: %w", err)
	}
	cmd.Params["doc_id"] = docID

	p.nextToken()

	// Expect IN
	if p.curToken.Type != TokenIn {
		return nil, fmt.Errorf("expected IN after doc_id")
	}
	p.nextToken()

	// Expect DATASET
	if p.curToken.Type != TokenDataset {
		return nil, fmt.Errorf("expected DATASET after IN")
	}
	p.nextToken()

	// Parse dataset_name (quoted string)
	datasetName, err := p.parseQuotedString()
	if err != nil {
		return nil, fmt.Errorf("expected dataset_name: %w", err)
	}
	cmd.Params["dataset_name"] = datasetName

	p.nextToken()

	// Semicolon is optional
	if p.curToken.Type == TokenSemicolon {
		p.nextToken()
	}

	return cmd, nil
}
