-- CPV nomenclature: 9,454 codes with Romanian names + EU emojis.
-- Loaded from samhallskod/cpv-eu (data sourced from official EU CPV 2008 XML).
BEGIN;

CREATE TABLE IF NOT EXISTS seap.cpv_codes (
  code           TEXT PRIMARY KEY,            -- 8-digit (no check digit), e.g. '45000000'
  code_full      TEXT,                         -- 8-digit + check, e.g. '45000000-7'
  name_ro        TEXT NOT NULL,
  name_en        TEXT,
  level          INT NOT NULL,                 -- 1=division (45), 2=group (450), 3=class (4500), ...
  division_code  TEXT NOT NULL,                -- first 2 digits + 6 zeroes, e.g. '45000000' (top-level parent)
  parent_code    TEXT,                         -- one level up
  emoji          TEXT,                         -- only set on division level
  imported_at    TIMESTAMPTZ DEFAULT now()
);

CREATE INDEX IF NOT EXISTS idx_cpv_division ON seap.cpv_codes(division_code);
CREATE INDEX IF NOT EXISTS idx_cpv_parent ON seap.cpv_codes(parent_code);
CREATE INDEX IF NOT EXISTS idx_cpv_level ON seap.cpv_codes(level);
CREATE INDEX IF NOT EXISTS idx_cpv_name_trgm ON seap.cpv_codes USING gin(name_ro gin_trgm_ops);


-- Helper: normalize "45123456-7" or "45123456" or empty → "45123456" (8-digit, no dash)
CREATE OR REPLACE FUNCTION seap.cpv_normalize(code TEXT)
RETURNS TEXT AS $$
BEGIN
  IF code IS NULL OR code = '' THEN RETURN NULL; END IF;
  -- Strip the check digit suffix (-X) and any whitespace
  RETURN regexp_replace(trim(code), '-[0-9]$', '');
END;
$$ LANGUAGE plpgsql IMMUTABLE STRICT;


-- Helper: get division code (first 2 digits + 6 zeros)
CREATE OR REPLACE FUNCTION seap.cpv_division(code TEXT)
RETURNS TEXT AS $$
BEGIN
  IF code IS NULL OR length(code) < 2 THEN RETURN NULL; END IF;
  RETURN substr(seap.cpv_normalize(code), 1, 2) || '000000';
END;
$$ LANGUAGE plpgsql IMMUTABLE STRICT;


-- Get name_ro for a code, fallback to division name, fallback to code itself
CREATE OR REPLACE FUNCTION seap.cpv_name(code TEXT)
RETURNS TEXT AS $$
DECLARE
  result TEXT;
BEGIN
  SELECT name_ro INTO result FROM seap.cpv_codes WHERE code = seap.cpv_normalize($1);
  IF result IS NOT NULL THEN RETURN result; END IF;
  SELECT name_ro INTO result FROM seap.cpv_codes WHERE code = seap.cpv_division($1);
  IF result IS NOT NULL THEN RETURN result; END IF;
  RETURN $1;
END;
$$ LANGUAGE plpgsql STABLE;


-- Get top-level category name + emoji for any code
CREATE OR REPLACE VIEW seap.cpv_division_lookup AS
SELECT code AS division_code, name_ro AS division_name, emoji
FROM seap.cpv_codes WHERE level = 1;


-- Add denormalized columns to announcements for fast queries
ALTER TABLE seap.announcements ADD COLUMN IF NOT EXISTS cpv_division TEXT;
ALTER TABLE seap.announcements ADD COLUMN IF NOT EXISTS cpv_name_ro  TEXT;

CREATE INDEX IF NOT EXISTS idx_ann_cpv_division ON seap.announcements(cpv_division);

COMMIT;
