package training

import (
	"context"
	"time"

	"github.com/google/uuid"
	"github.com/jackc/pgx/v5"
)

// CreateModuleContent creates new content for a module
func (s *Store) CreateModuleContent(ctx context.Context, content *ModuleContent) error {
	content.ID = uuid.New()
	content.CreatedAt = time.Now().UTC()
	content.UpdatedAt = content.CreatedAt

	// Auto-increment version
	var maxVersion int
	s.pool.QueryRow(ctx,
		"SELECT COALESCE(MAX(version), 0) FROM training_module_content WHERE module_id = $1",
		content.ModuleID).Scan(&maxVersion)
	content.Version = maxVersion + 1

	_, err := s.pool.Exec(ctx, `
		INSERT INTO training_module_content (
			id, module_id, version, content_format, content_body,
			summary, generated_by, llm_model, is_published,
			reviewed_by, reviewed_at, created_at, updated_at
		) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)
	`,
		content.ID, content.ModuleID, content.Version, string(content.ContentFormat), content.ContentBody,
		content.Summary, content.GeneratedBy, content.LLMModel, content.IsPublished,
		content.ReviewedBy, content.ReviewedAt, content.CreatedAt, content.UpdatedAt,
	)

	return err
}

// GetPublishedContent retrieves the published content for a module
func (s *Store) GetPublishedContent(ctx context.Context, moduleID uuid.UUID) (*ModuleContent, error) {
	var content ModuleContent
	var contentFormat string

	err := s.pool.QueryRow(ctx, `
		SELECT
			id, module_id, version, content_format, content_body,
			summary, generated_by, llm_model, is_published,
			reviewed_by, reviewed_at, created_at, updated_at
		FROM training_module_content
		WHERE module_id = $1 AND is_published = true
		ORDER BY version DESC
		LIMIT 1
	`, moduleID).Scan(
		&content.ID, &content.ModuleID, &content.Version, &contentFormat, &content.ContentBody,
		&content.Summary, &content.GeneratedBy, &content.LLMModel, &content.IsPublished,
		&content.ReviewedBy, &content.ReviewedAt, &content.CreatedAt, &content.UpdatedAt,
	)

	if err == pgx.ErrNoRows {
		return nil, nil
	}
	if err != nil {
		return nil, err
	}

	content.ContentFormat = ContentFormat(contentFormat)
	return &content, nil
}

// GetLatestContent retrieves the latest content (published or not) for a module
func (s *Store) GetLatestContent(ctx context.Context, moduleID uuid.UUID) (*ModuleContent, error) {
	var content ModuleContent
	var contentFormat string

	err := s.pool.QueryRow(ctx, `
		SELECT
			id, module_id, version, content_format, content_body,
			summary, generated_by, llm_model, is_published,
			reviewed_by, reviewed_at, created_at, updated_at
		FROM training_module_content
		WHERE module_id = $1
		ORDER BY version DESC
		LIMIT 1
	`, moduleID).Scan(
		&content.ID, &content.ModuleID, &content.Version, &contentFormat, &content.ContentBody,
		&content.Summary, &content.GeneratedBy, &content.LLMModel, &content.IsPublished,
		&content.ReviewedBy, &content.ReviewedAt, &content.CreatedAt, &content.UpdatedAt,
	)

	if err == pgx.ErrNoRows {
		return nil, nil
	}
	if err != nil {
		return nil, err
	}

	content.ContentFormat = ContentFormat(contentFormat)
	return &content, nil
}

// PublishContent marks a content version as published (unpublishes all others for that module)
func (s *Store) PublishContent(ctx context.Context, contentID uuid.UUID, reviewedBy uuid.UUID) error {
	now := time.Now().UTC()

	// Get module_id for this content
	var moduleID uuid.UUID
	err := s.pool.QueryRow(ctx,
		"SELECT module_id FROM training_module_content WHERE id = $1",
		contentID).Scan(&moduleID)
	if err != nil {
		return err
	}

	// Unpublish all existing content for this module
	_, err = s.pool.Exec(ctx,
		"UPDATE training_module_content SET is_published = false WHERE module_id = $1",
		moduleID)
	if err != nil {
		return err
	}

	// Publish the specified content
	_, err = s.pool.Exec(ctx, `
		UPDATE training_module_content SET
			is_published = true, reviewed_by = $2, reviewed_at = $3, updated_at = $3
		WHERE id = $1
	`, contentID, reviewedBy, now)

	return err
}
