use rusqlite::Connection;

pub fn init_db(conn: &Connection) -> Result<(), rusqlite::Error> {
    conn.execute(
        "CREATE TABLE IF NOT EXISTS clients (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            name TEXT NOT NULL,
            email TEXT,
            address TEXT,
            created_at TEXT DEFAULT CURRENT_TIMESTAMP
        )",
        [],
    )?;

    // Migrate clients table - add new columns (safe to re-run)
    let migration_columns = [
        "ALTER TABLE clients ADD COLUMN company TEXT",
        "ALTER TABLE clients ADD COLUMN phone TEXT",
        "ALTER TABLE clients ADD COLUMN tax_id TEXT",
        "ALTER TABLE clients ADD COLUMN payment_terms TEXT",
        "ALTER TABLE clients ADD COLUMN notes TEXT",
        "ALTER TABLE clients ADD COLUMN currency TEXT",
    ];
    for sql in &migration_columns {
        match conn.execute(sql, []) {
            Ok(_) => {}
            Err(e) => {
                let msg = e.to_string();
                if !msg.contains("duplicate column") {
                    return Err(e);
                }
            }
        }
    }

    conn.execute(
        "CREATE TABLE IF NOT EXISTS projects (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            client_id INTEGER,
            name TEXT NOT NULL,
            hourly_rate REAL DEFAULT 0,
            color TEXT DEFAULT '#F59E0B',
            archived INTEGER DEFAULT 0,
            created_at TEXT DEFAULT CURRENT_TIMESTAMP,
            FOREIGN KEY (client_id) REFERENCES clients(id)
        )",
        [],
    )?;

    // Migrate projects table - add budget columns (safe to re-run)
    let project_migrations = [
        "ALTER TABLE projects ADD COLUMN budget_hours REAL DEFAULT NULL",
        "ALTER TABLE projects ADD COLUMN budget_amount REAL DEFAULT NULL",
        "ALTER TABLE projects ADD COLUMN rounding_override INTEGER DEFAULT NULL",
        "ALTER TABLE projects ADD COLUMN timeline_override TEXT DEFAULT NULL",
        "ALTER TABLE projects ADD COLUMN notes TEXT",
        "ALTER TABLE projects ADD COLUMN currency TEXT",
    ];
    for sql in &project_migrations {
        match conn.execute(sql, []) {
            Ok(_) => {}
            Err(e) => {
                let msg = e.to_string();
                if !msg.contains("duplicate column") {
                    return Err(e);
                }
            }
        }
    }

    conn.execute(
        "CREATE TABLE IF NOT EXISTS tasks (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            project_id INTEGER NOT NULL,
            name TEXT NOT NULL,
            created_at TEXT DEFAULT CURRENT_TIMESTAMP,
            FOREIGN KEY (project_id) REFERENCES projects(id)
        )",
        [],
    )?;

    // Migrate tasks table (safe to re-run)
    let task_migrations = [
        "ALTER TABLE tasks ADD COLUMN estimated_hours REAL DEFAULT NULL",
        "ALTER TABLE tasks ADD COLUMN hourly_rate REAL DEFAULT NULL",
    ];
    for sql in &task_migrations {
        match conn.execute(sql, []) {
            Ok(_) => {}
            Err(e) => {
                let msg = e.to_string();
                if !msg.contains("duplicate column") {
                    return Err(e);
                }
            }
        }
    }

    conn.execute(
        "CREATE TABLE IF NOT EXISTS time_entries (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            project_id INTEGER NOT NULL,
            task_id INTEGER,
            description TEXT,
            start_time TEXT NOT NULL,
            end_time TEXT,
            duration INTEGER DEFAULT 0,
            created_at TEXT DEFAULT CURRENT_TIMESTAMP,
            FOREIGN KEY (project_id) REFERENCES projects(id),
            FOREIGN KEY (task_id) REFERENCES tasks(id)
        )",
        [],
    )?;

    // Migrate time_entries table
    let time_entry_migrations = [
        "ALTER TABLE time_entries ADD COLUMN billable INTEGER DEFAULT 1",
    ];
    for sql in &time_entry_migrations {
        match conn.execute(sql, []) {
            Ok(_) => {}
            Err(e) => {
                let msg = e.to_string();
                if !msg.contains("duplicate column") {
                    return Err(e);
                }
            }
        }
    }

    conn.execute(
        "CREATE TABLE IF NOT EXISTS invoices (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            client_id INTEGER NOT NULL,
            invoice_number TEXT NOT NULL,
            date TEXT NOT NULL,
            due_date TEXT,
            subtotal REAL DEFAULT 0,
            tax_rate REAL DEFAULT 0,
            tax_amount REAL DEFAULT 0,
            discount REAL DEFAULT 0,
            total REAL DEFAULT 0,
            notes TEXT,
            status TEXT DEFAULT 'draft',
            created_at TEXT DEFAULT CURRENT_TIMESTAMP,
            FOREIGN KEY (client_id) REFERENCES clients(id)
        )",
        [],
    )?;

    // Migrate invoices table - add template_id column (safe to re-run)
    let invoice_migrations = [
        "ALTER TABLE invoices ADD COLUMN template_id TEXT DEFAULT 'clean'",
    ];
    for sql in &invoice_migrations {
        match conn.execute(sql, []) {
            Ok(_) => {}
            Err(e) => {
                let msg = e.to_string();
                if !msg.contains("duplicate column") {
                    return Err(e);
                }
            }
        }
    }

    conn.execute(
        "CREATE TABLE IF NOT EXISTS invoice_items (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            invoice_id INTEGER NOT NULL,
            description TEXT NOT NULL,
            quantity REAL DEFAULT 1,
            rate REAL DEFAULT 0,
            amount REAL DEFAULT 0,
            time_entry_id INTEGER,
            FOREIGN KEY (invoice_id) REFERENCES invoices(id),
            FOREIGN KEY (time_entry_id) REFERENCES time_entries(id)
        )",
        [],
    )?;

    conn.execute(
        "CREATE TABLE IF NOT EXISTS tracked_apps (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            project_id INTEGER NOT NULL,
            exe_name TEXT NOT NULL,
            exe_path TEXT,
            display_name TEXT,
            FOREIGN KEY (project_id) REFERENCES projects(id)
        )",
        [],
    )?;

    conn.execute(
        "CREATE TABLE IF NOT EXISTS tags (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            name TEXT NOT NULL UNIQUE,
            color TEXT DEFAULT '#6B7280'
        )",
        [],
    )?;

    conn.execute(
        "CREATE TABLE IF NOT EXISTS entry_tags (
            entry_id INTEGER NOT NULL,
            tag_id INTEGER NOT NULL,
            PRIMARY KEY (entry_id, tag_id),
            FOREIGN KEY (entry_id) REFERENCES time_entries(id) ON DELETE CASCADE,
            FOREIGN KEY (tag_id) REFERENCES tags(id) ON DELETE CASCADE
        )",
        [],
    )?;

    conn.execute(
        "CREATE TABLE IF NOT EXISTS favorites (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            project_id INTEGER NOT NULL,
            task_id INTEGER,
            description TEXT,
            sort_order INTEGER DEFAULT 0,
            FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE,
            FOREIGN KEY (task_id) REFERENCES tasks(id) ON DELETE SET NULL
        )",
        [],
    )?;

    conn.execute(
        "CREATE TABLE IF NOT EXISTS recurring_entries (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            project_id INTEGER NOT NULL,
            task_id INTEGER,
            description TEXT,
            duration INTEGER DEFAULT 0,
            recurrence_rule TEXT NOT NULL,
            time_of_day TEXT DEFAULT '09:00',
            mode TEXT DEFAULT 'prompt',
            enabled INTEGER DEFAULT 1,
            last_triggered TEXT,
            created_at TEXT DEFAULT CURRENT_TIMESTAMP,
            FOREIGN KEY (project_id) REFERENCES projects(id),
            FOREIGN KEY (task_id) REFERENCES tasks(id)
        )",
        [],
    )?;

    conn.execute(
        "CREATE TABLE IF NOT EXISTS expenses (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            project_id INTEGER NOT NULL,
            client_id INTEGER,
            category TEXT DEFAULT 'other',
            description TEXT,
            amount REAL DEFAULT 0,
            date TEXT NOT NULL,
            receipt_path TEXT,
            invoiced INTEGER DEFAULT 0,
            created_at TEXT DEFAULT CURRENT_TIMESTAMP,
            FOREIGN KEY (project_id) REFERENCES projects(id),
            FOREIGN KEY (client_id) REFERENCES clients(id)
        )",
        [],
    )?;

    conn.execute(
        "CREATE TABLE IF NOT EXISTS timeline_events (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            project_id INTEGER NOT NULL,
            exe_name TEXT,
            exe_path TEXT,
            window_title TEXT,
            started_at TEXT NOT NULL,
            ended_at TEXT,
            duration INTEGER DEFAULT 0,
            FOREIGN KEY (project_id) REFERENCES projects(id)
        )",
        [],
    )?;

    conn.execute(
        "CREATE TABLE IF NOT EXISTS calendar_sources (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            name TEXT NOT NULL,
            type TEXT NOT NULL,
            url TEXT,
            last_synced TEXT,
            sync_interval INTEGER DEFAULT 30,
            enabled INTEGER DEFAULT 1,
            created_at TEXT DEFAULT CURRENT_TIMESTAMP
        )",
        [],
    )?;

    conn.execute(
        "CREATE TABLE IF NOT EXISTS calendar_events (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            source_id INTEGER NOT NULL,
            uid TEXT,
            summary TEXT,
            start_time TEXT,
            end_time TEXT,
            duration INTEGER DEFAULT 0,
            location TEXT,
            synced_at TEXT,
            FOREIGN KEY (source_id) REFERENCES calendar_sources(id) ON DELETE CASCADE
        )",
        [],
    )?;

    // Migrate calendar_events table - add description column (safe to re-run)
    let calendar_migrations = [
        "ALTER TABLE calendar_events ADD COLUMN description TEXT",
    ];
    for sql in &calendar_migrations {
        match conn.execute(sql, []) {
            Ok(_) => {}
            Err(e) => {
                let msg = e.to_string();
                if !msg.contains("duplicate column") {
                    return Err(e);
                }
            }
        }
    }

    conn.execute(
        "CREATE TABLE IF NOT EXISTS timesheet_locks (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            week_start TEXT NOT NULL UNIQUE,
            status TEXT DEFAULT 'locked',
            locked_at TEXT DEFAULT CURRENT_TIMESTAMP
        )",
        [],
    )?;

    conn.execute(
        "CREATE TABLE IF NOT EXISTS entry_templates (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            name TEXT NOT NULL,
            project_id INTEGER NOT NULL REFERENCES projects(id),
            task_id INTEGER REFERENCES tasks(id),
            description TEXT,
            duration INTEGER NOT NULL DEFAULT 0,
            billable INTEGER NOT NULL DEFAULT 1,
            created_at TEXT NOT NULL DEFAULT (datetime('now'))
        )",
        [],
    )?;

    conn.execute(
        "CREATE TABLE IF NOT EXISTS timesheet_rows (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            week_start TEXT NOT NULL,
            project_id INTEGER NOT NULL REFERENCES projects(id),
            task_id INTEGER REFERENCES tasks(id),
            sort_order INTEGER NOT NULL DEFAULT 0
        )",
        [],
    )?;

    conn.execute(
        "CREATE TABLE IF NOT EXISTS settings (
            key TEXT PRIMARY KEY,
            value TEXT
        )",
        [],
    )?;

    conn.execute(
        "CREATE TABLE IF NOT EXISTS invoice_payments (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            invoice_id INTEGER NOT NULL,
            amount REAL NOT NULL,
            date TEXT NOT NULL,
            method TEXT,
            notes TEXT,
            created_at TEXT DEFAULT CURRENT_TIMESTAMP,
            FOREIGN KEY (invoice_id) REFERENCES invoices(id) ON DELETE CASCADE
        )",
        [],
    )?;

    conn.execute(
        "CREATE TABLE IF NOT EXISTS recurring_invoices (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            client_id INTEGER NOT NULL,
            template_id TEXT,
            line_items_json TEXT NOT NULL,
            tax_rate REAL DEFAULT 0,
            discount REAL DEFAULT 0,
            notes TEXT,
            recurrence_rule TEXT NOT NULL,
            next_due_date TEXT NOT NULL,
            enabled INTEGER DEFAULT 1,
            created_at TEXT DEFAULT CURRENT_TIMESTAMP,
            FOREIGN KEY (client_id) REFERENCES clients(id)
        )",
        [],
    )?;

    // Insert default settings
    conn.execute(
        "INSERT OR IGNORE INTO settings (key, value) VALUES ('hourly_rate', '50')",
        [],
    )?;
    conn.execute(
        "INSERT OR IGNORE INTO settings (key, value) VALUES ('idle_detection', 'true')",
        [],
    )?;
    conn.execute(
        "INSERT OR IGNORE INTO settings (key, value) VALUES ('idle_timeout', '5')",
        [],
    )?;
    conn.execute(
        "INSERT OR IGNORE INTO settings (key, value) VALUES ('reminder_interval', '30')",
        [],
    )?;
    conn.execute(
        "INSERT OR IGNORE INTO settings (key, value) VALUES ('app_tracking_mode', 'auto')",
        [],
    )?;
    conn.execute(
        "INSERT OR IGNORE INTO settings (key, value) VALUES ('app_check_interval', '5')",
        [],
    )?;
    conn.execute("INSERT OR IGNORE INTO settings (key, value) VALUES ('goals_enabled', 'true')", [])?;
    conn.execute("INSERT OR IGNORE INTO settings (key, value) VALUES ('daily_goal_hours', '8')", [])?;
    conn.execute("INSERT OR IGNORE INTO settings (key, value) VALUES ('weekly_goal_hours', '40')", [])?;
    conn.execute("INSERT OR IGNORE INTO settings (key, value) VALUES ('rounding_enabled', 'false')", [])?;
    conn.execute("INSERT OR IGNORE INTO settings (key, value) VALUES ('rounding_increment', '15')", [])?;
    conn.execute("INSERT OR IGNORE INTO settings (key, value) VALUES ('rounding_method', 'nearest')", [])?;
    conn.execute("INSERT OR IGNORE INTO settings (key, value) VALUES ('theme_mode', 'dark')", [])?;
    conn.execute("INSERT OR IGNORE INTO settings (key, value) VALUES ('accent_color', 'amber')", [])?;
    conn.execute("INSERT OR IGNORE INTO settings (key, value) VALUES ('shortcut_toggle_timer', 'CmdOrCtrl+Shift+T')", [])?;
    conn.execute("INSERT OR IGNORE INTO settings (key, value) VALUES ('shortcut_show_app', 'CmdOrCtrl+Shift+Z')", [])?;
    conn.execute("INSERT OR IGNORE INTO settings (key, value) VALUES ('mini_timer_opacity', '90')", [])?;
    conn.execute("INSERT OR IGNORE INTO settings (key, value) VALUES ('timeline_recording', 'off')", [])?;

    Ok(())
}
