-- 025_anaf_datornici.sql
-- ANAF — Lista contribuabililor cu obligații fiscale restante (datornici).
-- Source: https://www.anaf.ro/restante/  (publicare trimestrială, Ord. 558/2016).
-- Plus lista albă (contribuabili FĂRĂ datorii) la /restante/listaalba.xhtml.
--
-- Bazele legale: ANAF publică trimestrial sumele restante peste plafoane —
--   500.000 lei (mari contribuabili), 250.000 lei (mijlocii), 100.000 lei
--   (mici), 10.000 lei (instituții publice). Sub plafon nu se publică.
--
-- KILLER USE CASE: cross-reference cu seap.announcements pentru a găsi
-- "firme datornice care au câștigat contracte publice" — interzis prin
-- art. 165 Legea 98/2016 dacă sunt obligații fiscale executorii.
--
-- IMPORTANT — limitări surse de date (2026-05-09):
--   1. anaf.ro/restante/index.xhtml e o aplicație JSF/PrimeFaces cu CAPTCHA
--      de tip kaptcha pe submit. Nu e bulk-scrapeable fără OCR/captcha-solver
--      pentru cele ~5K-15K rânduri per trimestru (×4 trim × ~10 ani = ~500K).
--   2. data.gov.ro publică UN SINGUR snapshot Q1-2016 (mari/mijlocii/micijuridice
--      CSV) — 140,780 rânduri, util ca baseline istoric.
--   3. listafirme.eu agregă ANAF datornici în spatele unui paywall API.
--
-- Strategia ingest:
--   - Faza 1 (THIS): schema + importer CSV pentru data.gov.ro Q1-2016 snapshot.
--     ~140K rânduri reale, validează schema end-to-end.
--   - Faza 2 (TODO): scraper cu captcha-solver extern (anti-captcha.com /
--     2captcha) pentru anaf.ro/restante/ live + arhive trimestriale dacă găsim.
--   - Faza 3: integrare cu firms.entities pentru profile badges + recipe-uri.

CREATE SCHEMA IF NOT EXISTS anaf;

-- ── Tabelă principală: datornici per (CUI × dată publicare) ─────────────────
CREATE TABLE IF NOT EXISTS anaf.datornici (
  cui                 text NOT NULL,                  -- fără prefix RO
  name                text,                           -- denumirea contribuabilului
  judet               text,                           -- 2026: nu e disponibil în CSV-urile data.gov.ro Q1-2016, dar e expus în XHTML live
  publication_date    date NOT NULL,                  -- prima zi a trimestrului (2016-01-01 = T1 2016)
  period_label        text NOT NULL,                  -- 'T1 2016' / 'T2 2024' etc.
  debtor_category     text,                           -- 'mari' | 'mijlocii' | 'mici' | 'institutii_publice' | 'persoane_fizice'
  debt_total          numeric(20,2),                  -- suma RON (principal + accesorii la toate cele 4 bugete)
  debt_principal      numeric(20,2),                  -- suma RON (principal la toate cele 4 bugete)
  debt_penalty        numeric(20,2),                  -- suma RON (accesorii la toate cele 4 bugete)
  debt_contested      numeric(20,2),                  -- suma RON contestată (necontestată = total - contested)
  -- Detaliu per buget (păstrăm pentru forensică, deși total/principal/penalty
  -- agregat e suficient pentru majoritatea recipes):
  budget_state_principal      numeric(20,2),
  budget_state_penalty        numeric(20,2),
  budget_state_contested      numeric(20,2),
  budget_social_principal     numeric(20,2),
  budget_social_penalty       numeric(20,2),
  budget_social_contested     numeric(20,2),
  budget_unemployment_principal numeric(20,2),
  budget_unemployment_penalty   numeric(20,2),
  budget_unemployment_contested numeric(20,2),
  budget_health_principal     numeric(20,2),
  budget_health_penalty       numeric(20,2),
  budget_health_contested     numeric(20,2),
  source_url          text,                           -- URL original al CSV / XHTML
  fetched_at          timestamptz DEFAULT now(),
  PRIMARY KEY (cui, publication_date)
);

CREATE INDEX IF NOT EXISTS idx_anaf_datornici_cui ON anaf.datornici(cui);
CREATE INDEX IF NOT EXISTS idx_anaf_datornici_pub_date ON anaf.datornici(publication_date DESC);
CREATE INDEX IF NOT EXISTS idx_anaf_datornici_total ON anaf.datornici(debt_total DESC NULLS LAST);
CREATE INDEX IF NOT EXISTS idx_anaf_datornici_category ON anaf.datornici(debtor_category);

-- ── Lista albă: firme FĂRĂ obligații restante (eligibile la SEAP) ───────────
-- Se publică separat la /restante/listaalba.xhtml. Mai puțin acționabilă, dar
-- utilă pentru a confirma negativ "firma X NU avea datorii când a câștigat
-- contractul Y" (când lipsește din .datornici nu înseamnă neapărat că nu
-- avea — poate fi sub plafon).
CREATE TABLE IF NOT EXISTS anaf.lista_alba (
  cui                 text NOT NULL,
  name                text,
  publication_date    date NOT NULL,
  period_label        text NOT NULL,
  source_url          text,
  fetched_at          timestamptz DEFAULT now(),
  PRIMARY KEY (cui, publication_date)
);

CREATE INDEX IF NOT EXISTS idx_anaf_lista_alba_cui ON anaf.lista_alba(cui);
CREATE INDEX IF NOT EXISTS idx_anaf_lista_alba_pub_date ON anaf.lista_alba(publication_date DESC);

-- ── View: cea mai recentă publicare per CUI (latest debt status) ────────────
CREATE OR REPLACE VIEW anaf.datornici_latest AS
SELECT DISTINCT ON (cui)
  cui, name, judet, publication_date, period_label, debtor_category,
  debt_total, debt_principal, debt_penalty, debt_contested
FROM anaf.datornici
ORDER BY cui, publication_date DESC;

COMMENT ON SCHEMA anaf IS 'ANAF (Agenția Națională de Administrare Fiscală) public registries';
COMMENT ON TABLE anaf.datornici IS 'Lista contribuabililor cu obligații restante, publicată trimestrial (Ord. 558/2016)';
COMMENT ON TABLE anaf.lista_alba IS 'Lista albă: contribuabili FĂRĂ obligații restante la data publicării';
COMMENT ON VIEW anaf.datornici_latest IS 'Cel mai recent snapshot al datoriilor per CUI';
