-- ============================================================================
-- Migration 009: Whistleblower / Hinweisgebersystem (HinSchG)
-- Implements the German Whistleblower Protection Act (Hinweisgeberschutzgesetz)
-- ============================================================================

-- Whistleblower reports table
CREATE TABLE IF NOT EXISTS whistleblower_reports (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES compliance_tenants(id) ON DELETE CASCADE,

    -- Identification
    reference_number VARCHAR(20) NOT NULL UNIQUE,  -- e.g. "WB-2026-0001"
    access_key VARCHAR(50) NOT NULL UNIQUE,        -- for anonymous reporter access

    -- Report content
    category VARCHAR(50) NOT NULL,   -- corruption, fraud, data_protection, discrimination, environment, competition, product_safety, tax_evasion, other
    status VARCHAR(50) NOT NULL DEFAULT 'new', -- new, acknowledged, under_review, investigation, measures_taken, closed, rejected
    title VARCHAR(500) NOT NULL,
    description TEXT NOT NULL,

    -- Reporter info (nullable for anonymous reports)
    is_anonymous BOOLEAN NOT NULL DEFAULT TRUE,
    reporter_name VARCHAR(255),
    reporter_email VARCHAR(255),
    reporter_phone VARCHAR(100),

    -- HinSchG deadlines
    received_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    deadline_acknowledgment TIMESTAMPTZ NOT NULL,  -- 7 days from received_at per HinSchG
    deadline_feedback TIMESTAMPTZ NOT NULL,        -- 3 months from received_at per HinSchG

    -- Status timestamps
    acknowledged_at TIMESTAMPTZ,
    closed_at TIMESTAMPTZ,

    -- Assignment
    assigned_to UUID,  -- user responsible for handling

    -- Audit trail (JSONB array of {timestamp, action, user_id, details})
    audit_trail JSONB NOT NULL DEFAULT '[]',

    -- Resolution
    resolution TEXT,

    -- Timestamps
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Whistleblower messages table (anonymous communication channel)
CREATE TABLE IF NOT EXISTS whistleblower_messages (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    report_id UUID NOT NULL REFERENCES whistleblower_reports(id) ON DELETE CASCADE,

    -- Message
    direction VARCHAR(30) NOT NULL,  -- reporter_to_admin, admin_to_reporter
    content TEXT NOT NULL,
    sent_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    read_at TIMESTAMPTZ
);

-- Whistleblower measures table (corrective measures)
CREATE TABLE IF NOT EXISTS whistleblower_measures (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    report_id UUID NOT NULL REFERENCES whistleblower_reports(id) ON DELETE CASCADE,

    -- Measure details
    title VARCHAR(500) NOT NULL,
    description TEXT,
    status VARCHAR(50) NOT NULL DEFAULT 'planned',  -- planned, in_progress, completed
    responsible VARCHAR(255),
    due_date TIMESTAMPTZ,
    completed_at TIMESTAMPTZ,

    -- Timestamps
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Sequence table for reference number generation
CREATE TABLE IF NOT EXISTS whistleblower_sequences (
    tenant_id UUID NOT NULL REFERENCES compliance_tenants(id) ON DELETE CASCADE,
    year INT NOT NULL,
    last_sequence INT NOT NULL DEFAULT 0,
    PRIMARY KEY (tenant_id, year)
);

-- ============================================================================
-- Indexes
-- ============================================================================

-- Report indexes
CREATE INDEX IF NOT EXISTS idx_whistleblower_reports_tenant ON whistleblower_reports(tenant_id);
CREATE INDEX IF NOT EXISTS idx_whistleblower_reports_access_key ON whistleblower_reports(access_key);
CREATE INDEX IF NOT EXISTS idx_whistleblower_reports_reference ON whistleblower_reports(reference_number);
CREATE INDEX IF NOT EXISTS idx_whistleblower_reports_status ON whistleblower_reports(tenant_id, status);
CREATE INDEX IF NOT EXISTS idx_whistleblower_reports_category ON whistleblower_reports(tenant_id, category);
CREATE INDEX IF NOT EXISTS idx_whistleblower_reports_received ON whistleblower_reports(tenant_id, received_at);
CREATE INDEX IF NOT EXISTS idx_whistleblower_reports_deadlines ON whistleblower_reports(deadline_acknowledgment, deadline_feedback)
    WHERE acknowledged_at IS NULL OR closed_at IS NULL;

-- Message indexes
CREATE INDEX IF NOT EXISTS idx_whistleblower_messages_report ON whistleblower_messages(report_id);
CREATE INDEX IF NOT EXISTS idx_whistleblower_messages_sent ON whistleblower_messages(report_id, sent_at);

-- Measure indexes
CREATE INDEX IF NOT EXISTS idx_whistleblower_measures_report ON whistleblower_measures(report_id);
CREATE INDEX IF NOT EXISTS idx_whistleblower_measures_status ON whistleblower_measures(report_id, status);

-- ============================================================================
-- Triggers
-- ============================================================================

-- Reuse existing update_updated_at_column function

-- Reports trigger
DROP TRIGGER IF EXISTS update_whistleblower_reports_updated_at ON whistleblower_reports;
CREATE TRIGGER update_whistleblower_reports_updated_at
    BEFORE UPDATE ON whistleblower_reports
    FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();

-- Measures trigger
DROP TRIGGER IF EXISTS update_whistleblower_measures_updated_at ON whistleblower_measures;
CREATE TRIGGER update_whistleblower_measures_updated_at
    BEFORE UPDATE ON whistleblower_measures
    FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();

-- ============================================================================
-- Comments
-- ============================================================================

COMMENT ON TABLE whistleblower_reports IS 'Whistleblower reports per HinSchG (Hinweisgeberschutzgesetz)';
COMMENT ON TABLE whistleblower_messages IS 'Anonymous communication channel between reporter and admin';
COMMENT ON TABLE whistleblower_measures IS 'Corrective measures taken for whistleblower reports';
COMMENT ON TABLE whistleblower_sequences IS 'Sequence numbers for reference number generation per tenant and year';

COMMENT ON COLUMN whistleblower_reports.reference_number IS 'Human-readable reference number (e.g. WB-2026-0001)';
COMMENT ON COLUMN whistleblower_reports.access_key IS 'Secret key for anonymous reporter to access their report';
COMMENT ON COLUMN whistleblower_reports.deadline_acknowledgment IS '7-day deadline per HinSchG §17 Abs. 1';
COMMENT ON COLUMN whistleblower_reports.deadline_feedback IS '3-month deadline per HinSchG §17 Abs. 2';
COMMENT ON COLUMN whistleblower_reports.audit_trail IS 'JSON array of audit entries tracking all actions on the report';
