"""v20 — Entity visibility lifecycle + connection_count.

Adds visibility lifecycle columns to the entity table:
  - visibility_status: extracted → promoted → active (or demoted)
  - connection_count: cached count of active claims referencing this entity
  - last_promoted_at: when the entity was last promoted
  - promotion_reason: why (e.g., 'high_connection_count', 'manual')

Also creates:
  - Indexes for efficient visibility-based queries
  - Trigger to auto-update connection_count on claim insert
  - dashboard_entities view combining peers + promoted entities
  - Backfill of connection_count from existing claims

Issue: #933
Milestone: v1.4.0 — Cortex for Everyone
"""
from __future__ import annotations

import logging

logger = logging.getLogger(__name__)

VERSION = 21
DESCRIPTION = "Entity visibility lifecycle + connection_count (#933)"

SQL_UP = """
-- New columns on entity
ALTER TABLE entity ADD COLUMN visibility_status TEXT NOT NULL DEFAULT 'extracted';
ALTER TABLE entity ADD COLUMN connection_count INTEGER NOT NULL DEFAULT 0;
ALTER TABLE entity ADD COLUMN last_promoted_at TEXT;
ALTER TABLE entity ADD COLUMN promotion_reason TEXT;

-- Indexes for visibility-based queries
CREATE INDEX IF NOT EXISTS idx_entity_visibility ON entity(owner_id, visibility_status);
CREATE INDEX IF NOT EXISTS idx_entity_connections ON entity(owner_id, connection_count DESC);

-- Partial index for promoted/active entities
CREATE INDEX IF NOT EXISTS idx_entity_promoted ON entity(owner_id, entity_type)
    WHERE visibility_status IN ('promoted', 'active');

-- Trigger: auto-update connection_count on claim insert
CREATE TRIGGER IF NOT EXISTS trg_claim_insert_entity_count
AFTER INSERT ON semantic_claim
BEGIN
    UPDATE entity SET connection_count = (
        SELECT COUNT(DISTINCT c.id) FROM semantic_claim c
        WHERE (c.subject_entity_id = NEW.subject_entity_id
               OR c.object_entity_id = NEW.subject_entity_id)
        AND c.status = 'active'
    ) WHERE id = NEW.subject_entity_id AND NEW.subject_entity_id IS NOT NULL;

    UPDATE entity SET connection_count = (
        SELECT COUNT(DISTINCT c.id) FROM semantic_claim c
        WHERE (c.subject_entity_id = NEW.object_entity_id
               OR c.object_entity_id = NEW.object_entity_id)
        AND c.status = 'active'
    ) WHERE id = NEW.object_entity_id AND NEW.object_entity_id IS NOT NULL;
END;

-- View: dashboard entities (actors + promoted)
CREATE VIEW IF NOT EXISTS dashboard_entities AS
SELECT 'peer' AS source, p.id, p.owner_id, p.display_name AS name,
       'actor' AS category, p.interaction_count AS relevance,
       p.last_interaction AS last_seen, p.created_at
FROM peer p WHERE p.relationship != 'unknown'
UNION ALL
SELECT 'entity' AS source, e.id, e.owner_id, e.canonical_name AS name,
       e.entity_type AS category, e.connection_count AS relevance,
       e.last_seen, e.created_at
FROM entity e WHERE e.visibility_status IN ('promoted', 'active')
ORDER BY relevance DESC;

-- Backfill connection_count from existing claims
UPDATE entity SET connection_count = (
    SELECT COUNT(DISTINCT c.id) FROM semantic_claim c
    WHERE (c.subject_entity_id = entity.id OR c.object_entity_id = entity.id)
    AND c.status = 'active'
) WHERE EXISTS (
    SELECT 1 FROM semantic_claim c
    WHERE c.subject_entity_id = entity.id OR c.object_entity_id = entity.id
);
"""

SQL_DOWN = """
DROP VIEW IF EXISTS dashboard_entities;
DROP TRIGGER IF EXISTS trg_claim_insert_entity_count;
DROP INDEX IF EXISTS idx_entity_promoted;
DROP INDEX IF EXISTS idx_entity_connections;
DROP INDEX IF EXISTS idx_entity_visibility;
-- SQLite does not support DROP COLUMN before 3.35.0; these columns
-- will persist but are harmless if unused.
"""
