package database

import (
	"database/sql"
	"log"
	"strings"

	_ "modernc.org/sqlite"
)

var DB *sql.DB

// Init 打开 SQLite 并执行必要的表结构初始化.
func Init(path string) {
	dsn := "file:" + path + "?_pragma=busy_timeout(5000)&_pragma=journal_mode(WAL)&_pragma=foreign_keys(1)"
	db, err := sql.Open("sqlite", dsn)
	if err != nil {
		log.Fatalf("open sqlite: %v", err)
	}
	DB = db
	if err := migrate(); err != nil {
		log.Fatalf("migrate: %v", err)
	}
}

func migrate() error {
	stmts := []string{
		`CREATE TABLE IF NOT EXISTS accounts (
            id         INTEGER PRIMARY KEY AUTOINCREMENT,
            name       TEXT NOT NULL,
            email      TEXT NOT NULL UNIQUE,
            password   TEXT NOT NULL DEFAULT '',
            smtp_host  TEXT NOT NULL,
            smtp_port  INTEGER NOT NULL,
            imap_host  TEXT NOT NULL,
            imap_port  INTEGER NOT NULL,
            use_tls    INTEGER DEFAULT 1,
            auth_type  TEXT DEFAULT 'basic',
            oauth_refresh_token TEXT,
            created_at DATETIME DEFAULT CURRENT_TIMESTAMP
        );`,
		`CREATE TABLE IF NOT EXISTS sent_logs (
            id         INTEGER PRIMARY KEY AUTOINCREMENT,
            account_id INTEGER NOT NULL,
            to_addr    TEXT NOT NULL,
            subject    TEXT,
            body       TEXT,
            status     TEXT,
            error      TEXT,
            created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
            FOREIGN KEY(account_id) REFERENCES accounts(id) ON DELETE CASCADE
        );`,
		`CREATE TABLE IF NOT EXISTS oauth_microsoft_pending (
            state          TEXT PRIMARY KEY,
            refresh_token  TEXT,
            email          TEXT,
            created_at     DATETIME DEFAULT CURRENT_TIMESTAMP
        );`,
	}
	for _, s := range stmts {
		if _, err := DB.Exec(s); err != nil {
			return err
		}
	}
	// 旧库升级：逐列添加（已存在则忽略错误）
	alters := []string{
		`ALTER TABLE accounts ADD COLUMN auth_type TEXT DEFAULT 'basic'`,
		`ALTER TABLE accounts ADD COLUMN oauth_refresh_token TEXT`,
	}
	for _, s := range alters {
		if _, err := DB.Exec(s); err != nil {
			if !strings.Contains(strings.ToLower(err.Error()), "duplicate column") {
				log.Printf("migrate alter note: %v", err)
			}
		}
	}
	return nil
}
