-- ============================================================================
-- Migration 011: Vendor Compliance Schema
-- Vendor Management, Contract/AVV Management, Findings, Templates
--
-- Implements DSGVO Art. 28 (Auftragsverarbeitung) requirements:
-- - Vendor registry with risk scoring and classification
-- - Contract/AVV document management with AI-assisted review
-- - Compliance findings from contract analysis
-- - Control instances for vendor-level control assessments
-- - Pre-filled templates for vendors, processing activities, and TOMs
-- ============================================================================

-- ============================================================================
-- Vendors (Service Provider Registry)
-- ============================================================================

CREATE TABLE IF NOT EXISTS vendor_vendors (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES compliance_tenants(id) ON DELETE CASCADE,

    -- Basic info
    name VARCHAR(255) NOT NULL,
    legal_form VARCHAR(100),
    country VARCHAR(10) NOT NULL DEFAULT 'DE', -- ISO 3166-1 alpha-2
    address JSONB, -- {street, city, postalCode, country, state}
    website VARCHAR(500),

    -- Contact
    contact_name VARCHAR(255),
    contact_email VARCHAR(255),
    contact_phone VARCHAR(100),
    contact_department VARCHAR(255),

    -- Role & Classification
    role VARCHAR(50) NOT NULL DEFAULT 'PROCESSOR', -- PROCESSOR, CONTROLLER, JOINT_CONTROLLER, SUB_PROCESSOR, THIRD_PARTY
    service_category VARCHAR(50), -- HOSTING, CRM, ERP, ANALYTICS, etc. (19 categories)
    service_description TEXT,
    data_access_level VARCHAR(50) DEFAULT 'NONE', -- NONE, POTENTIAL, ADMINISTRATIVE, CONTENT

    -- Processing & Compliance
    processing_locations JSONB DEFAULT '[]', -- [{country, region, isPrimary, isEU, isAdequate}]
    certifications JSONB DEFAULT '[]', -- ["ISO 27001", "SOC 2", etc.]

    -- Risk Scoring (0-100)
    inherent_risk_score INT DEFAULT 0,
    residual_risk_score INT DEFAULT 0,
    manual_risk_adjustment INT,

    -- Contract & Review
    review_frequency VARCHAR(50) DEFAULT 'ANNUAL', -- QUARTERLY, SEMI_ANNUAL, ANNUAL, BIENNIAL
    last_review_date TIMESTAMPTZ,
    next_review_date TIMESTAMPTZ,

    -- Links
    processing_activity_ids JSONB DEFAULT '[]', -- UUIDs of linked processing activities

    -- Status
    status VARCHAR(50) DEFAULT 'ACTIVE', -- ACTIVE, INACTIVE, PENDING_REVIEW, TERMINATED

    -- Template reference (if created from template)
    template_id VARCHAR(100),

    -- Audit
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    created_by UUID NOT NULL
);

-- ============================================================================
-- Contracts (including AVV/DPA)
-- ============================================================================

CREATE TABLE IF NOT EXISTS vendor_contracts (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES compliance_tenants(id) ON DELETE CASCADE,
    vendor_id UUID NOT NULL REFERENCES vendor_vendors(id) ON DELETE CASCADE,

    -- Document info
    file_name VARCHAR(500),
    original_name VARCHAR(500),
    mime_type VARCHAR(100),
    file_size BIGINT,
    storage_path VARCHAR(1000), -- MinIO path

    -- Classification
    document_type VARCHAR(50) NOT NULL, -- AVV, MSA, SLA, SCC, NDA, TOM_ANNEX, CERTIFICATION, SUB_PROCESSOR_LIST

    -- Metadata (extracted or manual)
    parties JSONB, -- [{name, role, address}]
    effective_date DATE,
    expiration_date DATE,
    auto_renewal BOOLEAN DEFAULT FALSE,
    renewal_notice_period VARCHAR(100),

    -- Review Status
    review_status VARCHAR(50) DEFAULT 'PENDING', -- PENDING, IN_PROGRESS, COMPLETED, FAILED
    review_completed_at TIMESTAMPTZ,
    compliance_score INT, -- 0-100

    -- Versioning
    version VARCHAR(50) DEFAULT '1.0',
    previous_version_id UUID REFERENCES vendor_contracts(id),

    -- Content (extracted text for analysis)
    extracted_text TEXT,
    page_count INT,

    -- Audit
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    created_by UUID NOT NULL
);

-- ============================================================================
-- Findings (from contract reviews)
-- ============================================================================

CREATE TABLE IF NOT EXISTS vendor_findings (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES compliance_tenants(id) ON DELETE CASCADE,
    contract_id UUID REFERENCES vendor_contracts(id) ON DELETE CASCADE,
    vendor_id UUID NOT NULL REFERENCES vendor_vendors(id) ON DELETE CASCADE,

    -- Classification
    finding_type VARCHAR(20) NOT NULL, -- OK, GAP, RISK, UNKNOWN
    category VARCHAR(50) NOT NULL, -- AVV_CONTENT, SUBPROCESSOR, INCIDENT, AUDIT_RIGHTS, DELETION, TOM, TRANSFER, LIABILITY, SLA, DATA_SUBJECT_RIGHTS, CONFIDENTIALITY, INSTRUCTION, TERMINATION, GENERAL
    severity VARCHAR(20) NOT NULL, -- LOW, MEDIUM, HIGH, CRITICAL

    -- Content
    title VARCHAR(500) NOT NULL,
    description TEXT,
    recommendation TEXT,

    -- Citations (from contract text)
    citations JSONB DEFAULT '[]', -- [{documentId, page, startChar, endChar, quotedText, quoteHash}]

    -- Workflow
    status VARCHAR(50) DEFAULT 'OPEN', -- OPEN, IN_PROGRESS, RESOLVED, ACCEPTED, FALSE_POSITIVE
    assignee VARCHAR(255),
    due_date DATE,
    resolution TEXT,
    resolved_at TIMESTAMPTZ,
    resolved_by UUID,

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

-- ============================================================================
-- Control Instances (applied controls per vendor)
-- ============================================================================

CREATE TABLE IF NOT EXISTS vendor_control_instances (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES compliance_tenants(id) ON DELETE CASCADE,
    vendor_id UUID NOT NULL REFERENCES vendor_vendors(id) ON DELETE CASCADE,

    -- Control reference
    control_id VARCHAR(100) NOT NULL, -- e.g., VND-TRF-01
    control_domain VARCHAR(50), -- TRANSFER, AUDIT, DELETION, INCIDENT, SUBPROCESSOR, TOM, CONTRACT, DATA_SUBJECT, SECURITY, GOVERNANCE

    -- Assessment
    status VARCHAR(50) DEFAULT 'PLANNED', -- PASS, PARTIAL, FAIL, NOT_APPLICABLE, PLANNED
    evidence_ids JSONB DEFAULT '[]',
    notes TEXT,

    -- Timing
    last_assessed_at TIMESTAMPTZ,
    last_assessed_by UUID,
    next_assessment_date TIMESTAMPTZ,

    -- Audit
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),

    UNIQUE(tenant_id, vendor_id, control_id)
);

-- ============================================================================
-- Templates (pre-filled templates for various entity types)
-- ============================================================================

CREATE TABLE IF NOT EXISTS compliance_templates (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID REFERENCES compliance_tenants(id) ON DELETE CASCADE, -- NULL for system templates

    -- Template info
    template_type VARCHAR(50) NOT NULL, -- VENDOR, PROCESSING_ACTIVITY, TOM, CONTROL_SET
    template_id VARCHAR(100) NOT NULL UNIQUE, -- e.g., tpl-vendor-cloud-iaas
    category VARCHAR(100), -- HR, SALES, MARKETING, CLOUD_INFRASTRUCTURE, etc.

    -- Content
    name_de VARCHAR(500) NOT NULL,
    name_en VARCHAR(500) NOT NULL,
    description_de TEXT,
    description_en TEXT,

    -- Template data (full template content as JSONB)
    template_data JSONB NOT NULL,

    -- Organization
    industry VARCHAR(100), -- IT, HEALTHCARE, FINANCE, MANUFACTURING, RETAIL, etc.
    tags JSONB DEFAULT '[]',

    -- Metadata
    is_system BOOLEAN DEFAULT FALSE, -- true = pre-installed, false = user-created
    is_active BOOLEAN DEFAULT TRUE,
    usage_count INT DEFAULT 0,

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

-- ============================================================================
-- Indexes: Vendors
-- ============================================================================

CREATE INDEX IF NOT EXISTS idx_vendor_vendors_tenant ON vendor_vendors(tenant_id);
CREATE INDEX IF NOT EXISTS idx_vendor_vendors_status ON vendor_vendors(tenant_id, status);
CREATE INDEX IF NOT EXISTS idx_vendor_vendors_role ON vendor_vendors(tenant_id, role);
CREATE INDEX IF NOT EXISTS idx_vendor_vendors_service_category ON vendor_vendors(tenant_id, service_category);
CREATE INDEX IF NOT EXISTS idx_vendor_vendors_next_review ON vendor_vendors(next_review_date)
    WHERE next_review_date IS NOT NULL;
CREATE INDEX IF NOT EXISTS idx_vendor_vendors_template_id ON vendor_vendors(template_id)
    WHERE template_id IS NOT NULL;

-- ============================================================================
-- Indexes: Contracts
-- ============================================================================

CREATE INDEX IF NOT EXISTS idx_vendor_contracts_tenant ON vendor_contracts(tenant_id);
CREATE INDEX IF NOT EXISTS idx_vendor_contracts_vendor ON vendor_contracts(vendor_id);
CREATE INDEX IF NOT EXISTS idx_vendor_contracts_document_type ON vendor_contracts(tenant_id, document_type);
CREATE INDEX IF NOT EXISTS idx_vendor_contracts_review_status ON vendor_contracts(tenant_id, review_status);
CREATE INDEX IF NOT EXISTS idx_vendor_contracts_expiration ON vendor_contracts(expiration_date)
    WHERE expiration_date IS NOT NULL;

-- ============================================================================
-- Indexes: Findings
-- ============================================================================

CREATE INDEX IF NOT EXISTS idx_vendor_findings_tenant ON vendor_findings(tenant_id);
CREATE INDEX IF NOT EXISTS idx_vendor_findings_vendor ON vendor_findings(vendor_id);
CREATE INDEX IF NOT EXISTS idx_vendor_findings_contract ON vendor_findings(contract_id)
    WHERE contract_id IS NOT NULL;
CREATE INDEX IF NOT EXISTS idx_vendor_findings_severity ON vendor_findings(tenant_id, severity);
CREATE INDEX IF NOT EXISTS idx_vendor_findings_status ON vendor_findings(tenant_id, status);
CREATE INDEX IF NOT EXISTS idx_vendor_findings_category ON vendor_findings(tenant_id, category);

-- ============================================================================
-- Indexes: Control Instances
-- ============================================================================

CREATE INDEX IF NOT EXISTS idx_vendor_control_instances_tenant ON vendor_control_instances(tenant_id);
CREATE INDEX IF NOT EXISTS idx_vendor_control_instances_vendor ON vendor_control_instances(vendor_id);
CREATE INDEX IF NOT EXISTS idx_vendor_control_instances_control_id ON vendor_control_instances(control_id);
CREATE INDEX IF NOT EXISTS idx_vendor_control_instances_status ON vendor_control_instances(tenant_id, status);

-- ============================================================================
-- Indexes: Templates
-- ============================================================================

CREATE INDEX IF NOT EXISTS idx_compliance_templates_type ON compliance_templates(template_type);
CREATE INDEX IF NOT EXISTS idx_compliance_templates_category ON compliance_templates(category)
    WHERE category IS NOT NULL;
CREATE INDEX IF NOT EXISTS idx_compliance_templates_industry ON compliance_templates(industry)
    WHERE industry IS NOT NULL;
CREATE INDEX IF NOT EXISTS idx_compliance_templates_system ON compliance_templates(is_system);
CREATE INDEX IF NOT EXISTS idx_compliance_templates_active ON compliance_templates(is_active);
CREATE INDEX IF NOT EXISTS idx_compliance_templates_template_id ON compliance_templates(template_id);

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

-- Reuse existing update_updated_at_column function

-- Vendors trigger
DROP TRIGGER IF EXISTS update_vendor_vendors_updated_at ON vendor_vendors;
CREATE TRIGGER update_vendor_vendors_updated_at
    BEFORE UPDATE ON vendor_vendors
    FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();

-- Contracts trigger
DROP TRIGGER IF EXISTS update_vendor_contracts_updated_at ON vendor_contracts;
CREATE TRIGGER update_vendor_contracts_updated_at
    BEFORE UPDATE ON vendor_contracts
    FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();

-- Findings trigger
DROP TRIGGER IF EXISTS update_vendor_findings_updated_at ON vendor_findings;
CREATE TRIGGER update_vendor_findings_updated_at
    BEFORE UPDATE ON vendor_findings
    FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();

-- Control instances trigger
DROP TRIGGER IF EXISTS update_vendor_control_instances_updated_at ON vendor_control_instances;
CREATE TRIGGER update_vendor_control_instances_updated_at
    BEFORE UPDATE ON vendor_control_instances
    FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();

-- Templates trigger
DROP TRIGGER IF EXISTS update_compliance_templates_updated_at ON compliance_templates;
CREATE TRIGGER update_compliance_templates_updated_at
    BEFORE UPDATE ON compliance_templates
    FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();

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

-- Table comments
COMMENT ON TABLE vendor_vendors IS 'Service provider registry for vendor compliance management (DSGVO Art. 28)';
COMMENT ON TABLE vendor_contracts IS 'Contract and AVV/DPA document management with AI-assisted review';
COMMENT ON TABLE vendor_findings IS 'Compliance findings from contract reviews and vendor assessments';
COMMENT ON TABLE vendor_control_instances IS 'Applied controls per vendor with assessment tracking';
COMMENT ON TABLE compliance_templates IS 'Pre-filled templates for vendors, processing activities, TOMs, and control sets';

-- Vendor column comments
COMMENT ON COLUMN vendor_vendors.role IS 'DSGVO role: PROCESSOR (Art. 28), CONTROLLER, JOINT_CONTROLLER (Art. 26), SUB_PROCESSOR, THIRD_PARTY';
COMMENT ON COLUMN vendor_vendors.data_access_level IS 'Level of access to personal data: NONE, POTENTIAL, ADMINISTRATIVE, CONTENT';
COMMENT ON COLUMN vendor_vendors.processing_locations IS 'JSONB array: Data processing locations with EU/adequacy status for transfer assessment';
COMMENT ON COLUMN vendor_vendors.certifications IS 'JSONB array: Vendor certifications (ISO 27001, SOC 2, etc.)';
COMMENT ON COLUMN vendor_vendors.inherent_risk_score IS 'Risk score (0-100) before controls are applied';
COMMENT ON COLUMN vendor_vendors.residual_risk_score IS 'Risk score (0-100) after controls are applied';
COMMENT ON COLUMN vendor_vendors.review_frequency IS 'How often the vendor must be reviewed: QUARTERLY, SEMI_ANNUAL, ANNUAL, BIENNIAL';
COMMENT ON COLUMN vendor_vendors.processing_activity_ids IS 'JSONB array: UUIDs linking to dsgvo_processing_activities entries';
COMMENT ON COLUMN vendor_vendors.template_id IS 'Reference to compliance_templates.template_id if vendor was created from a template';

-- Contract column comments
COMMENT ON COLUMN vendor_contracts.document_type IS 'Contract type: AVV (Auftragsverarbeitungsvertrag), MSA, SLA, SCC (Standard Contractual Clauses), NDA, TOM_ANNEX, CERTIFICATION, SUB_PROCESSOR_LIST';
COMMENT ON COLUMN vendor_contracts.storage_path IS 'MinIO object storage path for the uploaded document';
COMMENT ON COLUMN vendor_contracts.compliance_score IS 'AI-assessed compliance score (0-100) from contract review';
COMMENT ON COLUMN vendor_contracts.extracted_text IS 'Full text extracted from the document for AI analysis';
COMMENT ON COLUMN vendor_contracts.previous_version_id IS 'Self-referencing FK for contract version history';

-- Finding column comments
COMMENT ON COLUMN vendor_findings.finding_type IS 'Classification: OK (compliant), GAP (missing clause), RISK (problematic clause), UNKNOWN (could not determine)';
COMMENT ON COLUMN vendor_findings.category IS 'DSGVO Art. 28 requirement category the finding relates to';
COMMENT ON COLUMN vendor_findings.citations IS 'JSONB array: References to specific contract text passages with page/character offsets';
COMMENT ON COLUMN vendor_findings.status IS 'Workflow status: OPEN, IN_PROGRESS, RESOLVED, ACCEPTED (risk accepted), FALSE_POSITIVE';

-- Control instance column comments
COMMENT ON COLUMN vendor_control_instances.control_id IS 'Control identifier (e.g., VND-TRF-01 for transfer controls)';
COMMENT ON COLUMN vendor_control_instances.control_domain IS 'Control domain: TRANSFER, AUDIT, DELETION, INCIDENT, SUBPROCESSOR, TOM, CONTRACT, DATA_SUBJECT, SECURITY, GOVERNANCE';
COMMENT ON COLUMN vendor_control_instances.status IS 'Assessment result: PASS, PARTIAL, FAIL, NOT_APPLICABLE, PLANNED';
COMMENT ON COLUMN vendor_control_instances.evidence_ids IS 'JSONB array: References to evidence documents or contract IDs';

-- Template column comments
COMMENT ON COLUMN compliance_templates.template_type IS 'Template category: VENDOR, PROCESSING_ACTIVITY, TOM, CONTROL_SET';
COMMENT ON COLUMN compliance_templates.template_id IS 'Human-readable unique identifier (e.g., tpl-vendor-cloud-iaas)';
COMMENT ON COLUMN compliance_templates.template_data IS 'JSONB: Full template content including all pre-filled fields';
COMMENT ON COLUMN compliance_templates.is_system IS 'true = pre-installed system template, false = user-created tenant template';
COMMENT ON COLUMN compliance_templates.usage_count IS 'Number of times this template has been used to create entities';
