package repositories

import (
	"context"

	"github.com/CubeCraft-Creations/Extrudex/backend/internal/models"
	"github.com/jackc/pgx/v5/pgxpool"
)

// PrinterRepository handles database queries for printers.
type PrinterRepository struct {
	pool *pgxpool.Pool
}

// NewPrinterRepository creates a PrinterRepository backed by the given pool.
func NewPrinterRepository(pool *pgxpool.Pool) *PrinterRepository {
	return &PrinterRepository{pool: pool}
}

// scanPrinterWithType scans a printer row with JOINed printer_type.
func (r *PrinterRepository) scanPrinterWithType(row interface{ Scan(...interface{}) error }) (models.Printer, error) {
	var p models.Printer
	var pt models.PrinterType

	err := row.Scan(
		&p.ID, &p.Name, &p.PrinterTypeID,
		&p.Manufacturer, &p.Model,
		&p.MoonrakerURL, &p.MoonrakerAPIKey,
		&p.MQTTBrokerHost, &p.MQTTTopicPrefix,
		&p.MQTTTLSEnabled, &p.IsActive,
		&p.CreatedAt, &p.UpdatedAt,
		&pt.ID, &pt.Name,
		&pt.CreatedAt, &pt.UpdatedAt,
	)
	if err != nil {
		return p, err
	}

	p.PrinterType = &pt
	return p, nil
}

// GetAll returns all printers joined with their printer_type, ordered by name.
func (r *PrinterRepository) GetAll(ctx context.Context) ([]models.Printer, error) {
	rows, err := r.pool.Query(ctx, `
		SELECT p.id, p.name, p.printer_type_id,
		       p.manufacturer, p.model,
		       p.moonraker_url, p.moonraker_api_key,
		       p.mqtt_broker_host, p.mqtt_topic_prefix,
		       p.mqtt_tls_enabled, p.is_active,
		       p.created_at, p.updated_at,
		       pt.id, pt.name,
		       pt.created_at, pt.updated_at
		FROM printers p
		JOIN printer_types pt ON p.printer_type_id = pt.id
		ORDER BY p.name
	`)
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	var printers []models.Printer
	for rows.Next() {
		p, err := r.scanPrinterWithType(rows)
		if err != nil {
			return nil, err
		}
		printers = append(printers, p)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	if printers == nil {
		printers = []models.Printer{}
	}
	return printers, nil
}
