-- Migration 103: Verification evidence ledger and competitor status semantics
--
-- Goal:
--   fully_verified should mean "source-backed and resolved", not merely
--   "a competitor row was found". A product may be fully resolved when a
--   valid 1:1 competitor exists OR when research verified that no valid
--   public 1:1 competitor is available.

ALTER TABLE transceivers
  ADD COLUMN IF NOT EXISTS competitor_status VARCHAR(32) NOT NULL DEFAULT 'unknown',
  ADD COLUMN IF NOT EXISTS competitor_status_updated_at TIMESTAMPTZ,
  ADD COLUMN IF NOT EXISTS no_match_verified_at TIMESTAMPTZ,
  ADD COLUMN IF NOT EXISTS no_match_reason TEXT;

DO $$
BEGIN
  IF NOT EXISTS (
    SELECT 1
    FROM pg_constraint
    WHERE conname = 'transceivers_competitor_status_check'
  ) THEN
    ALTER TABLE transceivers
      ADD CONSTRAINT transceivers_competitor_status_check
      CHECK (competitor_status IN (
        'unknown',
        'matched',
        'no_valid_match',
        'needs_research',
        'ambiguous'
      ));
  END IF;
END $$;

UPDATE transceivers
SET competitor_status = CASE
      WHEN competitor_verified = true THEN 'matched'
      WHEN competitor_status = 'unknown' THEN 'needs_research'
      ELSE competitor_status
    END,
    competitor_status_updated_at = COALESCE(competitor_status_updated_at, NOW())
WHERE competitor_status IS NULL
   OR competitor_status = 'unknown'
   OR competitor_verified = true;

CREATE INDEX IF NOT EXISTS idx_transceivers_competitor_status
  ON transceivers (competitor_status);

CREATE INDEX IF NOT EXISTS idx_transceivers_no_valid_match
  ON transceivers (no_match_verified_at)
  WHERE competitor_status = 'no_valid_match';

CREATE TABLE IF NOT EXISTS transceiver_verification_evidence (
  id                  UUID DEFAULT gen_random_uuid() PRIMARY KEY,
  transceiver_id      UUID NOT NULL REFERENCES transceivers(id) ON DELETE CASCADE,
  verification_type   VARCHAR(40) NOT NULL CHECK (verification_type IN (
    'price',
    'image',
    'details',
    'competitor_match',
    'competitor_no_match',
    'artifact_quarantine'
  )),
  source_url          TEXT,
  source_vendor_id    UUID REFERENCES vendors(id) ON DELETE SET NULL,
  evidence_value      JSONB NOT NULL DEFAULT '{}'::jsonb,
  evidence_hash       TEXT,
  robot_name          TEXT NOT NULL DEFAULT 'unknown',
  confidence          NUMERIC(4,3) CHECK (confidence IS NULL OR confidence BETWEEN 0 AND 1),
  created_at          TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_verification_evidence_tx
  ON transceiver_verification_evidence (transceiver_id, verification_type, created_at DESC);

CREATE UNIQUE INDEX IF NOT EXISTS idx_verification_evidence_dedupe
  ON transceiver_verification_evidence (
    transceiver_id,
    verification_type,
    COALESCE(evidence_hash, ''),
    robot_name
  );

COMMENT ON COLUMN transceivers.competitor_status IS
  'Resolution state for competitor evidence: matched, no_valid_match, needs_research, ambiguous, unknown.';

COMMENT ON TABLE transceiver_verification_evidence IS
  'Append-only evidence ledger for TIP verification decisions. Stores source-backed proof for price, image, details, competitor matches and verified no-match states.';

-- Seed the ledger from already verified rows so TIP starts with an auditable
-- baseline instead of an empty proof table.
INSERT INTO transceiver_verification_evidence (
  transceiver_id,
  verification_type,
  source_url,
  source_vendor_id,
  evidence_value,
  evidence_hash,
  robot_name,
  confidence
)
SELECT DISTINCT ON (t.id)
  t.id,
  'price',
  po.url,
  po.source_vendor_id,
  jsonb_build_object(
    'price', po.price,
    'currency', po.currency,
    'observed_at', po.time
  ),
  md5(jsonb_build_object(
    'type', 'price',
    'price', po.price,
    'currency', po.currency,
    'url', COALESCE(po.url, '')
  )::text),
  'migration:103:price-backfill',
  1.0
FROM transceivers t
JOIN price_observations po ON po.transceiver_id = t.id
WHERE t.price_verified = true
  AND COALESCE(po.is_verified, true) = true
ORDER BY t.id, po.time DESC
ON CONFLICT DO NOTHING;

INSERT INTO transceiver_verification_evidence (
  transceiver_id,
  verification_type,
  source_url,
  evidence_value,
  evidence_hash,
  robot_name,
  confidence
)
SELECT
  id,
  'image',
  COALESCE(NULLIF(image_verified_url, ''), NULLIF(image_url, '')),
  jsonb_build_object('image_url', COALESCE(NULLIF(image_verified_url, ''), NULLIF(image_url, ''))),
  md5(jsonb_build_object('type', 'image', 'url', COALESCE(NULLIF(image_verified_url, ''), NULLIF(image_url, '')))::text),
  'migration:103:image-backfill',
  1.0
FROM transceivers
WHERE image_verified = true
  AND COALESCE(NULLIF(image_verified_url, ''), NULLIF(image_url, '')) IS NOT NULL
ON CONFLICT DO NOTHING;

INSERT INTO transceiver_verification_evidence (
  transceiver_id,
  verification_type,
  source_url,
  evidence_value,
  evidence_hash,
  robot_name,
  confidence
)
SELECT
  id,
  'details',
  COALESCE(NULLIF(details_source_url, ''), NULLIF(product_page_url, '')),
  jsonb_build_object(
    'form_factor', form_factor,
    'speed_gbps', speed_gbps,
    'reach_label', reach_label,
    'fiber_type', fiber_type
  ),
  md5(jsonb_build_object(
    'type', 'details',
    'source_url', COALESCE(NULLIF(details_source_url, ''), NULLIF(product_page_url, '')),
    'form_factor', form_factor,
    'speed_gbps', speed_gbps,
    'reach_label', reach_label,
    'fiber_type', fiber_type
  )::text),
  'migration:103:details-backfill',
  1.0
FROM transceivers
WHERE details_verified = true
  AND COALESCE(NULLIF(details_source_url, ''), NULLIF(product_page_url, '')) IS NOT NULL
ON CONFLICT DO NOTHING;

INSERT INTO transceiver_verification_evidence (
  transceiver_id,
  verification_type,
  evidence_value,
  evidence_hash,
  robot_name,
  confidence
)
SELECT DISTINCT ON (eq.flexoptix_id)
  eq.flexoptix_id,
  'competitor_match',
  jsonb_build_object(
    'equivalence_id', eq.id,
    'competitor_id', eq.competitor_id,
    'status', eq.status,
    'match_basis', eq.match_basis,
    'match_notes', eq.match_notes
  ),
  md5(jsonb_build_object(
    'type', 'competitor_match',
    'equivalence_id', eq.id,
    'competitor_id', eq.competitor_id,
    'status', eq.status
  )::text),
  'migration:103:competitor-match-backfill',
  eq.confidence
FROM transceiver_equivalences eq
WHERE eq.status IN ('approved', 'auto_approved')
ORDER BY eq.flexoptix_id, eq.confidence DESC, eq.updated_at DESC
ON CONFLICT DO NOTHING;

