// weatherstories_read.go executes weather story queries.
// Layer: adapters/outbound/postgres weather stories feature.
package postgres

import (
	"context"
	"database/sql"
	"errors"
	"fmt"

	"gitea.maximumdirect.net/ejr/weatherfeeder/model"
)

func (r *Repository) LatestWeatherStoryRun(ctx context.Context) (*model.WeatherStoryRun, error) {
	if r == nil || r.db == nil {
		return nil, fmt.Errorf("postgres repository is not configured")
	}

	var row weatherStoryRunParentRow
	err := r.db.QueryRowContext(ctx, queryLatestWeatherStoryRun).Scan(
		&row.EventID,
		&row.OfficeID,
		&row.AsOf,
	)
	if errors.Is(err, sql.ErrNoRows) {
		return nil, nil
	}
	if err != nil {
		return nil, fmt.Errorf("query latest weather story run: %w", err)
	}

	run := mapWeatherStoryRunParentRow(row)
	stories, err := r.loadWeatherStories(ctx, row.EventID)
	if err != nil {
		return nil, err
	}
	run.Stories = stories

	return &run, nil
}

func (r *Repository) LatestWeatherStory(ctx context.Context) (*model.WeatherStory, error) {
	if r == nil || r.db == nil {
		return nil, fmt.Errorf("postgres repository is not configured")
	}

	var row weatherStoryRow
	err := r.db.QueryRowContext(ctx, queryLatestWeatherStory).Scan(
		&row.StoryIndex,
		&row.OfficeID,
		&row.StartTime,
		&row.EndTime,
		&row.UpdatedAt,
		&row.Title,
		&row.Description,
		&row.AltText,
		&row.Priority,
		&row.StoryOrder,
		&row.DownloadURL,
	)
	if errors.Is(err, sql.ErrNoRows) {
		return nil, nil
	}
	if err != nil {
		return nil, fmt.Errorf("query latest weather story: %w", err)
	}

	story := mapWeatherStoryRow(row)
	return &story, nil
}

func (r *Repository) loadWeatherStories(ctx context.Context, eventID string) ([]model.WeatherStory, error) {
	rows, err := r.db.QueryContext(ctx, queryWeatherStoriesForRun, eventID)
	if err != nil {
		return nil, fmt.Errorf("query weather stories: %w", err)
	}
	defer rows.Close()

	out := make([]model.WeatherStory, 0)
	for rows.Next() {
		var row weatherStoryRow
		if err := rows.Scan(
			&row.StoryIndex,
			&row.OfficeID,
			&row.StartTime,
			&row.EndTime,
			&row.UpdatedAt,
			&row.Title,
			&row.Description,
			&row.AltText,
			&row.Priority,
			&row.StoryOrder,
			&row.DownloadURL,
		); err != nil {
			return nil, fmt.Errorf("scan weather story row: %w", err)
		}
		out = append(out, mapWeatherStoryRow(row))
	}
	if err := rows.Err(); err != nil {
		return nil, fmt.Errorf("iterate weather story rows: %w", err)
	}
	return out, nil
}
