// internal/db/db.go
package db

import (
	"fmt"
	"path/filepath"

	"github.com/jmoiron/sqlx"
	_ "github.com/mattn/go-sqlite3"
)

// DB holds the database connection
type DB struct {
	*sqlx.DB
}

// New creates a new DB instance
func New(dbPath string) (*DB, error) {
	// Ensure the directory exists
	dir := filepath.Dir(dbPath)
	if err := ensureDir(dir); err != nil {
		return nil, fmt.Errorf("failed to create database directory: %w", err)
	}

	// Connect to the database
	db, err := sqlx.Connect("sqlite3", dbPath)
	if err != nil {
		return nil, fmt.Errorf("failed to connect to database: %w", err)
	}

	// Set pragmas for better performance
	db.MustExec("PRAGMA journal_mode=WAL;")
	db.MustExec("PRAGMA foreign_keys=ON;")

	return &DB{db}, nil
}

// Initialize creates the database schema if it doesn't exist
func (db *DB) Initialize() error {
	// Create bots table
	_, err := db.Exec(`
	CREATE TABLE IF NOT EXISTS bots (
		id INTEGER PRIMARY KEY AUTOINCREMENT,
		pubkey TEXT NOT NULL UNIQUE,
		encrypted_privkey TEXT NOT NULL,
		name TEXT NOT NULL,
		display_name TEXT,
		bio TEXT,
		nip05 TEXT,
		zap_address TEXT,
		profile_picture TEXT,
		banner TEXT,
		created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
		owner_pubkey TEXT NOT NULL
	)`)
	if err != nil {
		return fmt.Errorf("failed to create bots table: %w", err)
	}

	// Create post_config table
	_, err = db.Exec(`
	CREATE TABLE IF NOT EXISTS post_config (
		id INTEGER PRIMARY KEY AUTOINCREMENT,
		bot_id INTEGER NOT NULL,
		hashtags TEXT,
		interval_minutes INTEGER NOT NULL DEFAULT 60,
		post_template TEXT,
		enabled BOOLEAN NOT NULL DEFAULT 0,
		FOREIGN KEY (bot_id) REFERENCES bots(id) ON DELETE CASCADE
	)`)
	if err != nil {
		return fmt.Errorf("failed to create post_config table: %w", err)
	}

	// Create media_config table
	_, err = db.Exec(`
	CREATE TABLE IF NOT EXISTS media_config (
		id INTEGER PRIMARY KEY AUTOINCREMENT,
		bot_id INTEGER NOT NULL,
		primary_service TEXT NOT NULL,
		fallback_service TEXT,
		nip94_server_url TEXT,
		blossom_server_url TEXT,
		FOREIGN KEY (bot_id) REFERENCES bots(id) ON DELETE CASCADE
	)`)
	if err != nil {
		return fmt.Errorf("failed to create media_config table: %w", err)
	}

	// Create relays table
	_, err = db.Exec(`
	CREATE TABLE IF NOT EXISTS relays (
		id INTEGER PRIMARY KEY AUTOINCREMENT,
		bot_id INTEGER NOT NULL,
		url TEXT NOT NULL,
		read BOOLEAN NOT NULL DEFAULT 1,
		write BOOLEAN NOT NULL DEFAULT 1,
		FOREIGN KEY (bot_id) REFERENCES bots(id) ON DELETE CASCADE,
		UNIQUE (bot_id, url)
	)`)
	if err != nil {
		return fmt.Errorf("failed to create relays table: %w", err)
	}

	// Create posts table
	_, err = db.Exec(`
	CREATE TABLE IF NOT EXISTS posts (
		id INTEGER PRIMARY KEY AUTOINCREMENT,
		bot_id INTEGER NOT NULL,
		content_filename TEXT,
		media_url TEXT,
		event_id TEXT,
		status TEXT NOT NULL,
		created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
		error TEXT,
		FOREIGN KEY (bot_id) REFERENCES bots(id) ON DELETE CASCADE
	)`)
	if err != nil {
		return fmt.Errorf("failed to create posts table: %w", err)
	}

	return nil
}

// ensureDir makes sure the directory exists
func ensureDir(dir string) error {
	return nil // This will be implemented in a file utility package
}