CREATE TABLE IF NOT EXISTS app_config (
                                          id INTEGER PRIMARY KEY CHECK (id = 1),
    timezone TEXT DEFAULT 'America/New_York',
    business_start INTEGER DEFAULT 9,
    business_end INTEGER DEFAULT 17,
    default_extension_days INTEGER DEFAULT 30,
    backup_enabled BOOLEAN DEFAULT 1,
    backup_interval_hours INTEGER DEFAULT 24,
    backup_retention_days INTEGER DEFAULT 30
    );

INSERT OR IGNORE INTO app_config (id) VALUES (1);

CREATE TABLE IF NOT EXISTS domains (name TEXT PRIMARY KEY);
INSERT OR IGNORE INTO domains (name) VALUES ('Vulnerability'), ('Privacy'), ('Compliance'), ('Incident');

CREATE TABLE IF NOT EXISTS departments (name TEXT PRIMARY KEY);
INSERT OR IGNORE INTO departments (name) VALUES ('Security'), ('IT'), ('Privacy'), ('Legal'), ('Compliance');

CREATE TABLE IF NOT EXISTS sla_policies (
                                            domain TEXT NOT NULL,
                                            severity TEXT NOT NULL,
                                            days_to_triage INTEGER NOT NULL DEFAULT 3,
                                            days_to_remediate INTEGER NOT NULL,
                                            max_extensions INTEGER NOT NULL DEFAULT 3,
                                            PRIMARY KEY (domain, severity),
    FOREIGN KEY(domain) REFERENCES domains(name) ON DELETE CASCADE
    );

INSERT OR IGNORE INTO sla_policies (domain, severity, days_to_triage, days_to_remediate, max_extensions) VALUES
    ('Vulnerability', 'Critical', 3, 14, 1), ('Vulnerability', 'High', 3, 30, 2),
    ('Privacy', 'Critical', 3, 3, 0), ('Privacy', 'High', 3, 7, 1),
    ('Incident', 'Critical', 3, 1, 0);

CREATE TABLE IF NOT EXISTS users (
                                     id INTEGER PRIMARY KEY AUTOINCREMENT,
                                     email TEXT UNIQUE NOT NULL,
                                     password_hash TEXT NOT NULL,
                                     full_name TEXT NOT NULL,
                                     global_role TEXT NOT NULL CHECK(global_role IN ('Sheriff', 'RangeHand', 'Wrangler', 'CircuitRider', 'Magistrate')),
    department TEXT NOT NULL DEFAULT 'Security',
    is_active BOOLEAN DEFAULT 1,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY(department) REFERENCES departments(name) ON DELETE SET DEFAULT
    );

CREATE TABLE IF NOT EXISTS sessions (
                                        session_token TEXT PRIMARY KEY,
                                        user_id INTEGER NOT NULL,
                                        expires_at DATETIME NOT NULL,
                                        FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE
    );

CREATE TABLE IF NOT EXISTS tickets (
                                       id INTEGER PRIMARY KEY AUTOINCREMENT,
                                       domain TEXT NOT NULL DEFAULT 'Vulnerability',
                                       source TEXT NOT NULL DEFAULT 'Manual',
                                       asset_identifier TEXT NOT NULL DEFAULT 'Default',
                                       cve_id TEXT,
                                       audit_id TEXT UNIQUE,
                                       compliance_tags TEXT,
                                       title TEXT NOT NULL,
                                       description TEXT,
                                       recommended_remediation TEXT,
                                       severity TEXT NOT NULL,
                                       status TEXT DEFAULT 'Waiting to be Triaged'
                                       CHECK(status IN (
                                       'Waiting to be Triaged',
                                       'Returned to Security',
                                       'Triaged',
                                       'Assigned Out',
                                       'Patched',
                                       'False Positive'
)),
    dedupe_hash TEXT UNIQUE NOT NULL,
    patch_evidence TEXT,
    accessible_to_internet BOOLEAN DEFAULT 0,
    assignee TEXT DEFAULT 'Unassigned',
    latest_comment TEXT DEFAULT '',

    assigned_at DATETIME,
    owner_viewed_at DATETIME,
    triage_due_date DATETIME,
    remediation_due_date DATETIME,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    patched_at DATETIME,
    FOREIGN KEY(domain) REFERENCES domains(name) ON DELETE SET DEFAULT
    );

CREATE INDEX IF NOT EXISTS idx_tickets_status ON tickets(status);
CREATE INDEX IF NOT EXISTS idx_tickets_severity ON tickets(severity);
CREATE INDEX IF NOT EXISTS idx_tickets_domain ON tickets(domain);
CREATE INDEX IF NOT EXISTS idx_tickets_source_asset ON tickets(source, asset_identifier);

CREATE TABLE IF NOT EXISTS ticket_assignments (
                                                  ticket_id INTEGER NOT NULL,
                                                  assignee TEXT NOT NULL,
                                                  role TEXT NOT NULL CHECK(role IN ('RangeHand', 'Wrangler', 'Magistrate')),
    PRIMARY KEY (ticket_id, assignee, role),
    FOREIGN KEY(ticket_id) REFERENCES tickets(id) ON DELETE CASCADE
    );

CREATE TABLE IF NOT EXISTS data_adapters (
                                             id INTEGER PRIMARY KEY AUTOINCREMENT,
                                             name TEXT NOT NULL UNIQUE,
                                             source_name TEXT NOT NULL,
                                             findings_path TEXT NOT NULL DEFAULT '.',
                                             mapping_title TEXT NOT NULL,
                                             mapping_asset TEXT NOT NULL,
                                             mapping_severity TEXT NOT NULL,
                                             mapping_description TEXT,
                                             mapping_remediation TEXT,
                                             created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
                                             updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE IF NOT EXISTS sync_logs (
                                         id INTEGER PRIMARY KEY AUTOINCREMENT,
                                         source TEXT NOT NULL,
                                         status TEXT NOT NULL,
                                         records_processed INTEGER NOT NULL,
                                         error_message TEXT,
                                         created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE IF NOT EXISTS draft_tickets (
                                             id INTEGER PRIMARY KEY AUTOINCREMENT,
                                             report_id TEXT NOT NULL,
                                             title TEXT DEFAULT '',
                                             description TEXT,
                                             severity TEXT DEFAULT 'Medium',
                                             asset_identifier TEXT DEFAULT '',
                                             recommended_remediation TEXT DEFAULT '',
                                             created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX IF NOT EXISTS idx_draft_tickets_report_id ON draft_tickets(report_id);

CREATE INDEX IF NOT EXISTS idx_assignments_assignee ON ticket_assignments(assignee);

CREATE INDEX IF NOT EXISTS idx_tickets_status_asset ON tickets(status, asset_identifier);
CREATE INDEX IF NOT EXISTS idx_tickets_updated_at ON tickets(updated_at);

CREATE INDEX IF NOT EXISTS idx_tickets_analytics ON tickets(status, severity, source);
CREATE INDEX IF NOT EXISTS idx_tickets_due_dates ON tickets(status, remediation_due_date, triage_due_date);
CREATE INDEX IF NOT EXISTS idx_tickets_source_status ON tickets(source, status);