-- Enable required extensions
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE EXTENSION IF NOT EXISTS "pg_trgm";

-- Update function for updated_at timestamps
CREATE OR REPLACE FUNCTION update_updated_at()
RETURNS TRIGGER AS $$
BEGIN
    NEW.updated_at = CURRENT_TIMESTAMP;
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

-- Update function for last_accessed
CREATE OR REPLACE FUNCTION update_last_accessed()
RETURNS TRIGGER AS $$
BEGIN
    NEW.last_accessed = CURRENT_TIMESTAMP;
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

-- ==========================================
-- USERS TABLE
-- ==========================================
CREATE TABLE IF NOT EXISTS users (
    id SERIAL PRIMARY KEY,
    username VARCHAR(255) UNIQUE NOT NULL,
    password_hash VARCHAR(255) NOT NULL,
    email VARCHAR(255) UNIQUE NOT NULL,
    role VARCHAR(50) DEFAULT 'admin',
    is_active BOOLEAN DEFAULT TRUE,
    mfa_enabled BOOLEAN DEFAULT FALSE,
    mfa_secret VARCHAR(255),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    last_login TIMESTAMP,
    failed_login_attempts INTEGER DEFAULT 0,
    locked_until TIMESTAMP
);

CREATE TRIGGER users_updated_at BEFORE UPDATE ON users
FOR EACH ROW EXECUTE FUNCTION update_updated_at();

-- ==========================================
-- SESSIONS TABLE
-- ==========================================
CREATE TABLE IF NOT EXISTS sessions (
    id VARCHAR(255) PRIMARY KEY,
    user_id INTEGER,
    data JSONB DEFAULT '{}',
    expires_at TIMESTAMP NOT NULL,
    last_accessed TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    user_agent TEXT,
    ip_address INET,
    is_remember_me BOOLEAN DEFAULT FALSE,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE TRIGGER sessions_accessed BEFORE UPDATE ON sessions
FOR EACH ROW EXECUTE FUNCTION update_last_accessed();

CREATE INDEX IF NOT EXISTS idx_sessions_user ON sessions(user_id);
CREATE INDEX IF NOT EXISTS idx_sessions_expires ON sessions(expires_at);

-- ==========================================
-- CSRF TOKENS TABLE
-- ==========================================
CREATE TABLE IF NOT EXISTS csrf_tokens (
    id VARCHAR(255) PRIMARY KEY,
    user_id INTEGER,
    session_id VARCHAR(255) NOT NULL,
    token_hash VARCHAR(255) UNIQUE NOT NULL,
    expires_at TIMESTAMP NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX IF NOT EXISTS idx_csrf_tokens_session ON csrf_tokens(session_id);
CREATE INDEX IF NOT EXISTS idx_csrf_tokens_expires ON csrf_tokens(expires_at);

-- ==========================================
-- MFA BACKUP CODES TABLE
-- ==========================================
CREATE TABLE IF NOT EXISTS mfa_backup_codes (
    id SERIAL PRIMARY KEY,
    user_id INTEGER NOT NULL,
    code_hash VARCHAR(255) NOT NULL,
    is_used BOOLEAN DEFAULT FALSE,
    used_at TIMESTAMP,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    CONSTRAINT fk_mfa_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);

CREATE INDEX IF NOT EXISTS idx_mfa_backup_codes_user ON mfa_backup_codes(user_id);
CREATE INDEX IF NOT EXISTS idx_mfa_backup_codes_unused ON mfa_backup_codes(user_id, is_used) WHERE is_used = FALSE;

-- ==========================================
-- SESSION AUDIT LOG TABLE
-- ==========================================
CREATE TABLE IF NOT EXISTS session_audit_log (
    id SERIAL PRIMARY KEY,
    user_id INTEGER NOT NULL,
    session_id VARCHAR(255),
    event VARCHAR(50) CHECK (event IN ('login', 'logout', 'expired', 'created', 'destroyed', 'mfa_enabled', 'mfa_disabled')) NOT NULL,
    ip_address INET,
    user_agent TEXT,
    metadata JSONB DEFAULT '{}',
    timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    CONSTRAINT fk_audit_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);

CREATE INDEX IF NOT EXISTS idx_audit_user ON session_audit_log(user_id);
CREATE INDEX IF NOT EXISTS idx_audit_timestamp ON session_audit_log(timestamp DESC);

-- ==========================================
-- CONFIG TABLE
-- ==========================================
CREATE TABLE IF NOT EXISTS config (
    id SERIAL PRIMARY KEY,
    key VARCHAR(255) UNIQUE NOT NULL,
    value JSONB NOT NULL,
    description TEXT,
    category VARCHAR(100) DEFAULT 'general',
    is_encrypted BOOLEAN DEFAULT FALSE,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_by INTEGER
);

CREATE TRIGGER config_updated_at BEFORE UPDATE ON config
FOR EACH ROW EXECUTE FUNCTION update_updated_at();

CREATE INDEX IF NOT EXISTS idx_config_category ON config(category);
CREATE INDEX IF NOT EXISTS idx_config_key ON config(key);

-- ==========================================
-- CUSTOMERS TABLE
-- ==========================================
CREATE TABLE IF NOT EXISTS customers (
    id SERIAL PRIMARY KEY,
    sap_customer_id VARCHAR(255),
    plesk_customer_id VARCHAR(255),
    name VARCHAR(255) NOT NULL,
    email VARCHAR(255),
    status VARCHAR(50) CHECK (status IN ('active', 'inactive', 'pending', 'deleted')) DEFAULT 'active',
    sync_status VARCHAR(50) CHECK (sync_status IN ('in_sync', 'pending_sync', 'sync_error', 'manual_override')) DEFAULT 'pending_sync',
    metadata JSONB DEFAULT '{}',
    last_sync TIMESTAMP,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE TRIGGER customers_updated_at BEFORE UPDATE ON customers
FOR EACH ROW EXECUTE FUNCTION update_updated_at();

CREATE UNIQUE INDEX IF NOT EXISTS idx_customer_mapping ON customers(sap_customer_id, plesk_customer_id) 
WHERE sap_customer_id IS NOT NULL AND plesk_customer_id IS NOT NULL;

CREATE INDEX IF NOT EXISTS idx_customers_status ON customers(status);
CREATE INDEX IF NOT EXISTS idx_customers_sync_status ON customers(sync_status);

-- ==========================================
-- SUBSCRIPTIONS TABLE
-- ==========================================
CREATE TABLE IF NOT EXISTS subscriptions (
    id SERIAL PRIMARY KEY,
    customer_id INTEGER NOT NULL,
    sap_subscription_id VARCHAR(255),
    plesk_subscription_id VARCHAR(255),
    sap_item_code VARCHAR(255),
    name VARCHAR(255) NOT NULL,
    description TEXT,
    start_date DATE,
    end_date DATE,
    billing_cycle VARCHAR(50) CHECK (billing_cycle IN ('monthly', 'annually', 'quarterly', 'custom')),
    status VARCHAR(50) CHECK (status IN ('active', 'suspended', 'terminated', 'pending')) DEFAULT 'active',
    sync_status VARCHAR(50) CHECK (sync_status IN ('in_sync', 'pending_sync', 'sync_error', 'manual_override')) DEFAULT 'pending_sync',
    pricing_data JSONB DEFAULT '{}',
    features JSONB DEFAULT '{}',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    CONSTRAINT fk_subscription_customer FOREIGN KEY (customer_id) REFERENCES customers(id) ON DELETE CASCADE
);

CREATE TRIGGER subscriptions_updated_at BEFORE UPDATE ON subscriptions
FOR EACH ROW EXECUTE FUNCTION update_updated_at();

CREATE INDEX IF NOT EXISTS idx_subscriptions_customer ON subscriptions(customer_id);
CREATE INDEX IF NOT EXISTS idx_subscriptions_status ON subscriptions(status);

-- ==========================================
-- USAGE METRICS TABLE
-- ==========================================
CREATE TYPE metric_type AS ENUM ('cpu', 'ram', 'disk', 'bandwidth', 'database', 'requests', 'emails');

CREATE TABLE IF NOT EXISTS usage_metrics (
    id SERIAL PRIMARY KEY,
    subscription_id INTEGER NOT NULL,
    metric_type metric_type NOT NULL,
    metric_value NUMERIC(15,4) NOT NULL,
    unit VARCHAR(50),
    recorded_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    metadata JSONB DEFAULT '{}',
    CONSTRAINT fk_usage_subscription FOREIGN KEY (subscription_id) REFERENCES subscriptions(id) ON DELETE CASCADE
);

CREATE INDEX IF NOT EXISTS idx_usage_subscription ON usage_metrics(subscription_id);
CREATE INDEX IF NOT EXISTS idx_usage_time ON usage_metrics(recorded_at DESC);

-- ==========================================
-- SYNC JOBS TABLE
-- ==========================================
CREATE TYPE sync_job_status AS ENUM ('pending', 'running', 'completed', 'failed', 'cancelled', 'paused');

CREATE TABLE IF NOT EXISTS sync_jobs (
    id SERIAL PRIMARY KEY,
    job_type VARCHAR(50) CHECK (job_type IN ('full_sync', 'incremental_sync', 'partial_sync', 'manual_sync')) NOT NULL,
    sync_direction VARCHAR(50) CHECK (sync_direction IN ('sap_to_plesk', 'plesk_to_sap', 'bidirectional')) NOT NULL,
    status sync_job_status DEFAULT 'pending',
    started_at TIMESTAMP,
    completed_at TIMESTAMP,
    records_processed INTEGER DEFAULT 0,
    records_failed INTEGER DEFAULT 0,
    records_skipped INTEGER DEFAULT 0,
    error_message TEXT,
    config_snapshot JSONB DEFAULT '{}',
    progress_percentage NUMERIC(5,2) DEFAULT 0,
    estimated_completion TIMESTAMP,
    created_by INTEGER,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE TRIGGER sync_jobs_updated_at BEFORE UPDATE ON sync_jobs
FOR EACH ROW EXECUTE FUNCTION update_updated_at();

CREATE INDEX IF NOT EXISTS idx_sync_status ON sync_jobs(status);
CREATE INDEX IF NOT EXISTS idx_sync_created_at ON sync_jobs(created_at DESC);

-- ==========================================
-- NOTIFICATIONS TABLE
-- ==========================================
CREATE TABLE IF NOT EXISTS notifications (
    id SERIAL PRIMARY KEY,
    type VARCHAR(50) CHECK (type IN ('info', 'success', 'warning', 'error', 'sync', 'security', 'system')) NOT NULL,
    title VARCHAR(255) NOT NULL,
    message TEXT NOT NULL,
    sent_via JSONB NOT NULL DEFAULT '[]',
    recipient_type VARCHAR(50) DEFAULT 'admin',
    recipient VARCHAR(255),
    is_read BOOLEAN DEFAULT FALSE,
    is_actionable BOOLEAN DEFAULT FALSE,
    action_url TEXT,
    data JSONB DEFAULT '{}',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    read_at TIMESTAMP
);

CREATE INDEX IF NOT EXISTS idx_notifications_unread ON notifications(is_read) WHERE is_read = FALSE;
CREATE INDEX IF NOT EXISTS idx_notifications_created_at ON notifications(created_at DESC);

-- ==========================================
-- WEBHOOKS TABLE
-- ==========================================
CREATE TABLE IF NOT EXISTS webhooks (
    id SERIAL PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    url VARCHAR(500) NOT NULL,
    secret_key VARCHAR(255),
    events JSONB NOT NULL DEFAULT '[]',
    is_active BOOLEAN DEFAULT TRUE,
    retry_policy JSONB DEFAULT '{"max_retries":3,"retry_delay":60}',
    last_triggered TIMESTAMP,
    last_status VARCHAR(50),
    last_error TEXT,
    trigger_count INTEGER DEFAULT 0,
    success_count INTEGER DEFAULT 0,
    failure_count INTEGER DEFAULT 0,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    created_by INTEGER
);

CREATE INDEX IF NOT EXISTS idx_webhooks_active ON webhooks(is_active) WHERE is_active = TRUE;

-- ==========================================
-- BACKUPS TABLE
-- ==========================================
CREATE TABLE IF NOT EXISTS backups (
    id SERIAL PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    type VARCHAR(50) CHECK (type IN ('full', 'config', 'data', 'database')) NOT NULL,
    backup_path VARCHAR(500),
    size_bytes BIGINT,
    checksum VARCHAR(255),
    is_restorable BOOLEAN DEFAULT TRUE,
    metadata JSONB DEFAULT '{}',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    created_by INTEGER
);

-- ==========================================
-- SYNC LOGS TABLE
-- ==========================================
CREATE TABLE IF NOT EXISTS sync_logs (
    id SERIAL PRIMARY KEY,
    sync_job_id INTEGER NOT NULL,
    entity_type VARCHAR(50) NOT NULL,
    entity_id VARCHAR(255) NOT NULL,
    action VARCHAR(50) NOT NULL,
    status VARCHAR(50) NOT NULL,
    error_message TEXT,
    metadata JSONB DEFAULT '{}',
    timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    resolution_status VARCHAR(50) DEFAULT 'pending',
    resolution_action VARCHAR(50),
    resolved_by INTEGER REFERENCES users(id) ON DELETE SET NULL,
    resolved_at TIMESTAMP,
    conflict_details JSONB,
    CONSTRAINT fk_sync_log_job FOREIGN KEY (sync_job_id) REFERENCES sync_jobs(id) ON DELETE CASCADE
);

CREATE INDEX IF NOT EXISTS idx_sync_logs_job ON sync_logs(sync_job_id);
CREATE INDEX IF NOT EXISTS idx_sync_logs_timestamp ON sync_logs(timestamp DESC);
CREATE INDEX IF NOT EXISTS idx_sync_logs_status ON sync_logs(status);
CREATE INDEX IF NOT EXISTS idx_sync_logs_resolution ON sync_logs(resolution_status) WHERE resolution_status = 'pending';

-- ==========================================
-- PLESK SERVERS TABLE
-- ==========================================
CREATE TABLE IF NOT EXISTS plesk_servers (
    id SERIAL PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    host VARCHAR(255) NOT NULL,
    port INTEGER DEFAULT 8443,
    api_key TEXT,
    username VARCHAR(255),
    password_hash TEXT,
    use_https BOOLEAN DEFAULT TRUE,
    verify_ssl BOOLEAN DEFAULT TRUE,
    two_factor_enabled BOOLEAN DEFAULT FALSE,
    two_factor_method VARCHAR(50),
    connection_status VARCHAR(50) DEFAULT 'unknown',
    last_connected TIMESTAMP,
    is_active BOOLEAN DEFAULT TRUE,
    metadata JSONB DEFAULT '{}',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE TRIGGER plesk_servers_updated_at BEFORE UPDATE ON plesk_servers
FOR EACH ROW EXECUTE FUNCTION update_updated_at();

CREATE INDEX IF NOT EXISTS idx_plesk_active ON plesk_servers(is_active) WHERE is_active = TRUE;
CREATE INDEX IF NOT EXISTS idx_plesk_host ON plesk_servers(host);

-- ==========================================
-- SAP SERVERS TABLE
-- ==========================================
CREATE TABLE IF NOT EXISTS sap_servers (
    id SERIAL PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    host VARCHAR(255) NOT NULL,
    port INTEGER DEFAULT 50000,
    company_db VARCHAR(255) NOT NULL,
    username VARCHAR(255),
    password_hash TEXT,
    use_ssl BOOLEAN DEFAULT TRUE,
    timeout_seconds INTEGER DEFAULT 30,
    connection_status VARCHAR(50) DEFAULT 'unknown',
    last_connected TIMESTAMP,
    is_active BOOLEAN DEFAULT TRUE,
    metadata JSONB DEFAULT '{}',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE TRIGGER sap_servers_updated_at BEFORE UPDATE ON sap_servers
FOR EACH ROW EXECUTE FUNCTION update_updated_at();

CREATE INDEX IF NOT EXISTS idx_sap_active ON sap_servers(is_active) WHERE is_active = TRUE;
CREATE INDEX IF NOT EXISTS idx_sap_company ON sap_servers(company_db);

-- ==========================================
-- SCHEDULED SYNC TABLE
-- ==========================================
CREATE TABLE IF NOT EXISTS scheduled_syncs (
    id SERIAL PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    schedule_type VARCHAR(50) CHECK (schedule_type IN ('daily', 'weekly', 'monthly', 'custom')) NOT NULL,
    schedule_config JSONB NOT NULL,
    job_type VARCHAR(50) NOT NULL,
    sync_direction VARCHAR(50) NOT NULL,
    plesk_server_id INTEGER,
    sap_server_id INTEGER,
    is_active BOOLEAN DEFAULT TRUE,
    last_run TIMESTAMP,
    next_run TIMESTAMP,
    created_by INTEGER,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    CONSTRAINT fk_scheduled_plesk FOREIGN KEY (plesk_server_id) REFERENCES plesk_servers(id) ON DELETE SET NULL,
    CONSTRAINT fk_scheduled_sap FOREIGN KEY (sap_server_id) REFERENCES sap_servers(id) ON DELETE SET NULL
);

CREATE TRIGGER scheduled_syncs_updated_at BEFORE UPDATE ON scheduled_syncs
FOR EACH ROW EXECUTE FUNCTION update_updated_at();

CREATE INDEX IF NOT EXISTS idx_scheduled_active ON scheduled_syncs(is_active) WHERE is_active = TRUE;
CREATE INDEX IF NOT EXISTS idx_scheduled_next_run ON scheduled_syncs(next_run);

-- ==========================================
-- PRICING CONFIG TABLE
-- ==========================================
CREATE TABLE IF NOT EXISTS pricing_config (
    id SERIAL PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    metric_type metric_type NOT NULL,
    unit VARCHAR(50) NOT NULL,
    rate_per_unit NUMERIC(10,4) NOT NULL,
    currency VARCHAR(3) DEFAULT 'EUR',
    is_active BOOLEAN DEFAULT TRUE,
    valid_from DATE DEFAULT CURRENT_DATE,
    valid_to DATE,
    notes TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    UNIQUE(metric_type, unit, valid_from)
);

CREATE INDEX IF NOT EXISTS idx_pricing_active ON pricing_config(is_active) WHERE is_active = TRUE;
CREATE INDEX IF NOT EXISTS idx_pricing_metric ON pricing_config(metric_type);

-- ==========================================
-- BILLING RECORDS TABLE
-- ==========================================
CREATE TABLE IF NOT EXISTS billing_records (
    id SERIAL PRIMARY KEY,
    subscription_id INTEGER NOT NULL,
    customer_id INTEGER NOT NULL,
    period_start DATE NOT NULL,
    period_end DATE NOT NULL,
    usage_data JSONB NOT NULL,
    calculated_amount NUMERIC(12,2) NOT NULL,
    currency VARCHAR(3) DEFAULT 'EUR',
    sap_invoice_id VARCHAR(255),
    sap_invoice_number VARCHAR(255),
    invoice_status VARCHAR(50) CHECK (invoice_status IN ('draft', 'pending', 'sent', 'synced', 'failed')) DEFAULT 'draft',
    invoice_pdf_path VARCHAR(500),
    notes TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    sent_to_sap_at TIMESTAMP,
    CONSTRAINT fk_billing_subscription FOREIGN KEY (subscription_id) REFERENCES subscriptions(id) ON DELETE CASCADE,
    CONSTRAINT fk_billing_customer FOREIGN KEY (customer_id) REFERENCES customers(id) ON DELETE CASCADE
);

CREATE TRIGGER billing_records_updated_at BEFORE UPDATE ON billing_records
FOR EACH ROW EXECUTE FUNCTION update_updated_at();

CREATE INDEX IF NOT EXISTS idx_billing_period ON billing_records(period_start, period_end);
CREATE INDEX IF NOT EXISTS idx_billing_status ON billing_records(invoice_status);
CREATE INDEX IF NOT EXISTS idx_billing_customer ON billing_records(customer_id);

-- ==========================================
-- ALERT THRESHOLDS TABLE
-- ==========================================
CREATE TABLE IF NOT EXISTS alert_thresholds (
    id SERIAL PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    subscription_id INTEGER,
    metric_type metric_type NOT NULL,
    threshold_value NUMERIC(15,4) NOT NULL,
    comparison_operator VARCHAR(10) CHECK (comparison_operator IN ('>', '>=', '<', '<=', '=')) NOT NULL,
    action VARCHAR(50) CHECK (action IN ('notify', 'notify_and_suspend', 'notify_and_limit')) NOT NULL,
    notification_channels JSONB DEFAULT '["email"]',
    is_active BOOLEAN DEFAULT TRUE,
    last_triggered TIMESTAMP,
    created_by INTEGER,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE TRIGGER alert_thresholds_updated_at BEFORE UPDATE ON alert_thresholds
FOR EACH ROW EXECUTE FUNCTION update_updated_at();

CREATE INDEX IF NOT EXISTS idx_alerts_active ON alert_thresholds(is_active) WHERE is_active = TRUE;
CREATE INDEX IF NOT EXISTS idx_alerts_subscription ON alert_thresholds(subscription_id);
CREATE INDEX IF NOT EXISTS idx_alerts_metric ON alert_thresholds(metric_type);

-- ==========================================
-- ALERT HISTORY TABLE
-- ==========================================
CREATE TABLE IF NOT EXISTS alert_history (
    id SERIAL PRIMARY KEY,
    threshold_id INTEGER NOT NULL,
    subscription_id INTEGER,
    actual_value NUMERIC(15,4) NOT NULL,
    triggered_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    action_taken VARCHAR(50),
    notification_sent BOOLEAN DEFAULT FALSE,
    notification_error TEXT,
    CONSTRAINT fk_alert_history_threshold FOREIGN KEY (threshold_id) REFERENCES alert_thresholds(id) ON DELETE CASCADE
);

CREATE INDEX IF NOT EXISTS idx_alert_history_triggered ON alert_history(triggered_at DESC);
CREATE INDEX IF NOT EXISTS idx_alert_history_threshold ON alert_history(threshold_id);

-- Add server_id columns to customers table
ALTER TABLE customers ADD COLUMN IF NOT EXISTS plesk_server_id INTEGER REFERENCES plesk_servers(id) ON DELETE SET NULL;
ALTER TABLE customers ADD COLUMN IF NOT EXISTS sap_server_id INTEGER REFERENCES sap_servers(id) ON DELETE SET NULL;
ALTER TABLE customers ADD COLUMN IF NOT EXISTS last_conflict TIMESTAMP;
CREATE INDEX IF NOT EXISTS idx_customers_plesk_server ON customers(plesk_server_id);
CREATE INDEX IF NOT EXISTS idx_customers_sap_server ON customers(sap_server_id);

-- Add server_id columns to sync_jobs table
ALTER TABLE sync_jobs ADD COLUMN IF NOT EXISTS plesk_server_id INTEGER REFERENCES plesk_servers(id) ON DELETE SET NULL;
ALTER TABLE sync_jobs ADD COLUMN IF NOT EXISTS sap_server_id INTEGER REFERENCES sap_servers(id) ON DELETE SET NULL;
ALTER TABLE sync_jobs ADD COLUMN IF NOT EXISTS scheduled_sync_id INTEGER REFERENCES scheduled_syncs(id) ON DELETE SET NULL;
CREATE INDEX IF NOT EXISTS idx_sync_jobs_plesk_server ON sync_jobs(plesk_server_id);
CREATE INDEX IF NOT EXISTS idx_sync_jobs_sap_server ON sync_jobs(sap_server_id);

CREATE INDEX IF NOT EXISTS idx_sync_logs_job ON sync_logs(sync_job_id);
CREATE INDEX IF NOT EXISTS idx_sync_logs_timestamp ON sync_logs(timestamp DESC);
CREATE INDEX IF NOT EXISTS idx_sync_logs_status ON sync_logs(status);

-- ==========================================
-- INITIAL DATA
-- ==========================================

-- Default configuration
INSERT INTO config (key, value, description, category) VALUES
    ('sync.default_direction', '"sap_to_plesk"', 'Default sync direction', 'sync'),
    ('sync.conflict_resolution', '"timestamp_based"', 'Default conflict resolution strategy', 'sync'),
    ('sync.interval_minutes', '60', 'Default sync interval in minutes', 'sync'),
    ('auth.session_timeout', '1800', 'Session timeout in seconds (30 min)', 'auth'),
    ('auth.max_login_attempts', '5', 'Max failed login attempts before lockout', 'auth'),
    ('auth.lockout_duration', '3600', 'Lockout duration in seconds (1 hour)', 'auth'),
    ('notifications.email_enabled', 'true', 'Enable email notifications', 'notifications'),
    ('notifications.webhook_enabled', 'true', 'Enable webhook notifications', 'notifications'),
    ('system.initialized', 'true', 'System initialization flag', 'system')
ON CONFLICT (key) DO NOTHING;

-- Note: Default admin user will be created dynamically by the backend on first startup
-- Username: admin
-- Password: [REDACTED] (default, can be changed via environment variables)
-- IMPORTANT: Change password immediately after first login