"""insolvency_watchlist + insolvency_hits — vigiar devedores e os seus prazos.

A watchlist é alimentada pelo Sabichão: ao criar um cliente, o NIF é empurrado
para cá. **Nunca se remove nada** — um cliente desactivado continua a ser um
devedor cujo processo de insolvência interessa acompanhar; é requisito
explícito, não descuido.

Traz também três alterações pequenas mas necessárias noutras tabelas:

* `monitoring_type='client'` — sem isto os clientes ficavam só listados na
  watchlist e nunca eram scrapeados, portanto a tab Intel do Sabichão não teria
  processos nem publicações para mostrar.
* `alerts_config.kind` — os alertas de insolvência têm de coexistir com os de
  processo sem se misturarem na mesma lista de destinatários.
* `alerts_log.process_id` passa a NULLABLE e ganha `announcement_id`. Era
  `NOT NULL` com FK para `processes`, o que tornava impossível registar o envio
  de um alerta de insolvência — que não tem processo associado.
"""
from alembic import op

revision = "0021"
down_revision = "0020"
branch_labels = None
depends_on = None


def upgrade() -> None:
    op.execute(
        """
        CREATE TABLE insolvency_watchlist (
            id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
            nif CHAR(9) NOT NULL UNIQUE,
            name TEXT,
            source TEXT NOT NULL DEFAULT 'manual'
                CHECK (source IN ('manual','sabichao','company')),
            external_ref TEXT,
            active BOOLEAN NOT NULL DEFAULT true,
            notes TEXT,
            created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
            updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
        );
        CREATE INDEX ix_watchlist_active ON insolvency_watchlist(active) WHERE active;

        CREATE TABLE insolvency_hits (
            id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
            announcement_id UUID NOT NULL
                REFERENCES cire_announcements(id) ON DELETE CASCADE,
            watchlist_id UUID REFERENCES insolvency_watchlist(id) ON DELETE SET NULL,
            company_id UUID REFERENCES companies(id) ON DELETE SET NULL,
            matched_nif CHAR(9) NOT NULL,
            matched_name TEXT,
            matched_role TEXT,
            claim_deadline DATE,
            acknowledged_at TIMESTAMPTZ,
            acknowledged_by UUID REFERENCES users(id) ON DELETE SET NULL,
            notified_at TIMESTAMPTZ,
            created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
            UNIQUE (announcement_id, matched_nif)
        );
        CREATE INDEX ix_hits_deadline ON insolvency_hits(claim_deadline)
            WHERE acknowledged_at IS NULL;
        CREATE INDEX ix_hits_pending_notify ON insolvency_hits(notified_at)
            WHERE notified_at IS NULL;
        CREATE INDEX ix_hits_company ON insolvency_hits(company_id);

        -- Clientes passam a entidades monitorizadas de pleno direito.
        ALTER TABLE companies DROP CONSTRAINT IF EXISTS companies_monitoring_type_check;
        ALTER TABLE companies ADD CONSTRAINT companies_monitoring_type_check
            CHECK (monitoring_type IN ('internal','competitor','analysis','related','client'));

        ALTER TABLE alerts_config ADD COLUMN IF NOT EXISTS kind TEXT NOT NULL DEFAULT 'process';
        ALTER TABLE alerts_config DROP CONSTRAINT IF EXISTS alerts_config_kind_check;
        ALTER TABLE alerts_config ADD CONSTRAINT alerts_config_kind_check
            CHECK (kind IN ('process','insolvency','digest'));

        ALTER TABLE alerts_log ALTER COLUMN process_id DROP NOT NULL;
        ALTER TABLE alerts_log ADD COLUMN IF NOT EXISTS announcement_id UUID
            REFERENCES cire_announcements(id) ON DELETE CASCADE;
        CREATE INDEX IF NOT EXISTS ix_alerts_log_announcement
            ON alerts_log(announcement_id) WHERE announcement_id IS NOT NULL;
        """
    )

    # Destinatário por defeito dos avisos de insolvência. Fica editável nas
    # Definições; semeamos para a funcionalidade não nascer muda.
    op.execute(
        """
        INSERT INTO alerts_config (company_id, type, target, enabled, kind)
        SELECT NULL, 'email', 'geral@segunor.pt', true, 'insolvency'
        WHERE NOT EXISTS (
            SELECT 1 FROM alerts_config WHERE kind = 'insolvency' AND type = 'email'
        )
        """
    )


def downgrade() -> None:
    op.execute(
        """
        DROP TABLE IF EXISTS insolvency_hits;
        DROP TABLE IF EXISTS insolvency_watchlist;
        ALTER TABLE alerts_config DROP CONSTRAINT IF EXISTS alerts_config_kind_check;
        ALTER TABLE alerts_config DROP COLUMN IF EXISTS kind;
        ALTER TABLE alerts_log DROP COLUMN IF EXISTS announcement_id;
        ALTER TABLE companies DROP CONSTRAINT IF EXISTS companies_monitoring_type_check;
        ALTER TABLE companies ADD CONSTRAINT companies_monitoring_type_check
            CHECK (monitoring_type IN ('internal','competitor','analysis','related'));
        """
    )
