// observations_read.go executes observation and present-weather queries.
// Layer: adapters/outbound/postgres observations feature.
package postgres

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

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

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

	var row observationParentRow
	err := r.db.QueryRowContext(ctx, queryLatestObservation).Scan(
		&row.EventID,
		&row.StationID,
		&row.StationName,
		&row.ObservedAt,
		&row.ConditionCode,
		&row.IsDay,
		&row.TextDescription,
		&row.TemperatureC,
		&row.DewpointC,
		&row.WindDirectionDegrees,
		&row.WindSpeedKmh,
		&row.WindGustKmh,
		&row.BarometricPressurePa,
		&row.VisibilityMeters,
		&row.RelativeHumidityPercent,
		&row.ApparentTemperatureC,
	)
	if errors.Is(err, sql.ErrNoRows) {
		return nil, nil
	}
	if err != nil {
		return nil, fmt.Errorf("query latest observation: %w", err)
	}

	obs := mapObservationParentRow(row)

	presentWeather, err := r.loadObservationPresentWeather(ctx, row.EventID)
	if err != nil {
		return nil, err
	}
	obs.PresentWeather = presentWeather

	return &obs, nil
}

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

	out := make([]model.PresentWeather, 0)
	for rows.Next() {
		var row observationPresentWeatherRow
		if err := rows.Scan(&row.WeatherIndex, &row.RawText); err != nil {
			return nil, fmt.Errorf("scan observation present weather row: %w", err)
		}
		pw, err := mapObservationPresentWeatherRow(row)
		if err != nil {
			return nil, fmt.Errorf("decode observation present weather row (index=%d): %w", row.WeatherIndex, err)
		}
		out = append(out, pw)
	}
	if err := rows.Err(); err != nil {
		return nil, fmt.Errorf("iterate observation present weather rows: %w", err)
	}
	return out, nil
}
