package repository

import (
	"context"
	"lune/talentscale/internal/domain"

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

type postgresNotificationRepository struct {
	db *pgxpool.Pool
}

func NewPostgresNotificationRepository(db *pgxpool.Pool) domain.NotificationRepository {
	return &postgresNotificationRepository{db: db}
}

func (r *postgresNotificationRepository) Create(ctx context.Context, n *domain.Notification) error {
	query := `INSERT INTO notifications (id, user_id, title, message, type, is_read, metadata, created_at)
	          VALUES ($1, $2, $3, $4, $5, $6, $7, $8)`
	_, err := r.db.Exec(ctx, query, n.ID, n.UserID, n.Title, n.Message, n.Type, n.IsRead, n.Metadata, n.CreatedAt)
	return err
}

func (r *postgresNotificationRepository) GetByID(ctx context.Context, id uuid.UUID) (*domain.Notification, error) {
	query := `SELECT id, user_id, title, message, type, is_read, metadata, created_at
	          FROM notifications WHERE id = $1`
	var n domain.Notification
	err := r.db.QueryRow(ctx, query, id).Scan(&n.ID, &n.UserID, &n.Title, &n.Message, &n.Type, &n.IsRead, &n.Metadata, &n.CreatedAt)
	if err != nil {
		return nil, err
	}
	return &n, nil
}

func (r *postgresNotificationRepository) ListByUser(ctx context.Context, userID uuid.UUID) ([]domain.Notification, error) {
	query := `SELECT id, user_id, title, message, type, is_read, metadata, created_at
	          FROM notifications WHERE user_id = $1 ORDER BY created_at DESC`
	rows, err := r.db.Query(ctx, query, userID)
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	var notifications []domain.Notification
	for rows.Next() {
		var n domain.Notification
		if err := rows.Scan(&n.ID, &n.UserID, &n.Title, &n.Message, &n.Type, &n.IsRead, &n.Metadata, &n.CreatedAt); err != nil {
			return nil, err
		}
		notifications = append(notifications, n)
	}
	return notifications, nil
}

func (r *postgresNotificationRepository) MarkAsRead(ctx context.Context, id uuid.UUID) error {
	query := `UPDATE notifications SET is_read = TRUE WHERE id = $1`
	_, err := r.db.Exec(ctx, query, id)
	return err
}
