package store

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

	"github.com/google/uuid"
)

// CreateDNSRecord inserts a new DNS record tracking entry.
func (s *Store) CreateDNSRecord(rec DNSRecord) (DNSRecord, error) {
	if rec.ID == "" {
		rec.ID = uuid.New().String()
	}
	now := Now()
	rec.CreatedAt = now
	rec.UpdatedAt = now

	_, err := s.db.Exec(
		`INSERT INTO dns_records (id, fqdn, provider_record_id, consumer_type, consumer_id, created_at, updated_at)
		 VALUES (?, ?, ?, ?, ?, ?, ?)`,
		rec.ID, rec.FQDN, rec.ProviderRecordID, rec.ConsumerType, rec.ConsumerID, rec.CreatedAt, rec.UpdatedAt,
	)
	if err != nil {
		return DNSRecord{}, fmt.Errorf("insert dns_record: %w", err)
	}
	return rec, nil
}

// GetDNSRecordByFQDN returns a DNS record by its FQDN.
func (s *Store) GetDNSRecordByFQDN(fqdn string) (DNSRecord, error) {
	var rec DNSRecord
	err := s.db.QueryRow(
		`SELECT id, fqdn, provider_record_id, consumer_type, consumer_id, created_at, updated_at
		 FROM dns_records WHERE fqdn = ?`, fqdn,
	).Scan(&rec.ID, &rec.FQDN, &rec.ProviderRecordID, &rec.ConsumerType, &rec.ConsumerID, &rec.CreatedAt, &rec.UpdatedAt)
	if errors.Is(err, sql.ErrNoRows) {
		return DNSRecord{}, fmt.Errorf("dns record %s: %w", fqdn, ErrNotFound)
	}
	if err != nil {
		return DNSRecord{}, fmt.Errorf("query dns_record: %w", err)
	}
	return rec, nil
}

// ListDNSRecords returns all tracked DNS records.
func (s *Store) ListDNSRecords() ([]DNSRecord, error) {
	rows, err := s.db.Query(
		`SELECT id, fqdn, provider_record_id, consumer_type, consumer_id, created_at, updated_at
		 FROM dns_records ORDER BY fqdn`,
	)
	if err != nil {
		return nil, fmt.Errorf("query dns_records: %w", err)
	}
	defer rows.Close()

	var records []DNSRecord
	for rows.Next() {
		var rec DNSRecord
		if err := rows.Scan(&rec.ID, &rec.FQDN, &rec.ProviderRecordID, &rec.ConsumerType, &rec.ConsumerID, &rec.CreatedAt, &rec.UpdatedAt); err != nil {
			return nil, fmt.Errorf("scan dns_record: %w", err)
		}
		records = append(records, rec)
	}
	return records, rows.Err()
}

// GetDNSRecordsByConsumer returns all DNS records for a specific consumer.
func (s *Store) GetDNSRecordsByConsumer(consumerType, consumerID string) ([]DNSRecord, error) {
	rows, err := s.db.Query(
		`SELECT id, fqdn, provider_record_id, consumer_type, consumer_id, created_at, updated_at
		 FROM dns_records WHERE consumer_type = ? AND consumer_id = ? ORDER BY fqdn`,
		consumerType, consumerID,
	)
	if err != nil {
		return nil, fmt.Errorf("query dns_records by consumer: %w", err)
	}
	defer rows.Close()

	var records []DNSRecord
	for rows.Next() {
		var rec DNSRecord
		if err := rows.Scan(&rec.ID, &rec.FQDN, &rec.ProviderRecordID, &rec.ConsumerType, &rec.ConsumerID, &rec.CreatedAt, &rec.UpdatedAt); err != nil {
			return nil, fmt.Errorf("scan dns_record: %w", err)
		}
		records = append(records, rec)
	}
	return records, rows.Err()
}

// UpdateDNSRecordProviderID updates the provider record ID for an existing DNS record.
func (s *Store) UpdateDNSRecordProviderID(fqdn, providerRecordID string) error {
	_, err := s.db.Exec(
		`UPDATE dns_records SET provider_record_id = ?, updated_at = ? WHERE fqdn = ?`,
		providerRecordID, Now(), fqdn,
	)
	if err != nil {
		return fmt.Errorf("update dns_record provider_id: %w", err)
	}
	return nil
}

// DeleteDNSRecord removes a DNS record by FQDN.
func (s *Store) DeleteDNSRecord(fqdn string) error {
	_, err := s.db.Exec(`DELETE FROM dns_records WHERE fqdn = ?`, fqdn)
	if err != nil {
		return fmt.Errorf("delete dns_record: %w", err)
	}
	return nil
}

// DeleteDNSRecordsByConsumer removes all DNS records for a specific consumer.
func (s *Store) DeleteDNSRecordsByConsumer(consumerType, consumerID string) error {
	_, err := s.db.Exec(
		`DELETE FROM dns_records WHERE consumer_type = ? AND consumer_id = ?`,
		consumerType, consumerID,
	)
	if err != nil {
		return fmt.Errorf("delete dns_records by consumer: %w", err)
	}
	return nil
}
