package main

import (
	"database/sql"
	"encoding/json"
	"fmt"
	"os"
	"path/filepath"
	"strings"
	"time"

	_ "modernc.org/sqlite"
)

type Image struct {
	ImageURL string `json:"image_url"`
	Title    string `json:"title"`
}

type Article struct {
	ID        int
	Keyword   string
	Slug      string
	Images    []Image
	AITitle   string
	AIContent string
	CreatedAt string
}

func streamArticles(dataFolder string, batchSize int, out chan<- Article, errChan chan<- error) {
	defer close(out)

	absPath := projectPath(dataFolder)
	entries, err := os.ReadDir(absPath)
	if err != nil {
		errChan <- fmt.Errorf("error reading data folder %s: %w", absPath, err)
		return
	}

	for _, entry := range entries {
		if entry.IsDir() {
			continue
		}
		ext := strings.ToLower(filepath.Ext(entry.Name()))
		if ext != ".db" && ext != ".sqlite" {
			continue
		}

		dbPath := filepath.Join(absPath, entry.Name())
		db, err := sql.Open("sqlite", dbPath)
		if err != nil {
			errChan <- fmt.Errorf("error opening database %s: %w", dbPath, err)
			return
		}

		lastID := 0
		for {
			query := `
				SELECT id, keyword, slug, images, ai_title, ai_content, created_at 
				FROM posts 
				WHERE id > ?
					AND images IS NOT NULL AND images != '' AND images != '[]'
					AND ai_content IS NOT NULL AND TRIM(ai_content) != ''
				ORDER BY id ASC
				LIMIT ?
			`
			rows, err := db.Query(query, lastID, batchSize)
			if err != nil {
				db.Close()
				errChan <- fmt.Errorf("error querying database: %w", err)
				return
			}

			fetched := false
			for rows.Next() {
				var (
					id           int
					keyword      string
					slug         string
					imagesJSON   string
					aiTitle      sql.NullString
					aiContent    string
					createdAt    string
				)

				if err := rows.Scan(&id, &keyword, &slug, &imagesJSON, &aiTitle, &aiContent, &createdAt); err != nil {
					rows.Close()
					db.Close()
					errChan <- fmt.Errorf("error scanning row: %w", err)
					return
				}

				fetched = true
				lastID = id

				var images []Image
				if err := json.Unmarshal([]byte(imagesJSON), &images); err != nil {
					images = []Image{}
				}

				title := ""
				if aiTitle.Valid {
					title = aiTitle.String
				}

				out <- Article{
					ID:        id,
					Keyword:   keyword,
					Slug:      slug,
					Images:    images,
					AITitle:   title,
					AIContent: aiContent,
					CreatedAt: createdAt,
				}
			}
			rows.Close()

			if !fetched {
				break
			}
		}

		db.Close()
	}

	errChan <- nil
}

func parseTime(t string) time.Time {
	for _, layout := range []string{
		"2006-01-02 15:04:05",
		"2006-01-02T15:04:05Z",
		"2006-01-02",
	} {
		if parsed, err := time.Parse(layout, t); err == nil {
			return parsed
		}
	}
	return time.Now()
}
