-- AI Ticket Analyzer feature
-- Stores versioned analyses of Autotask tickets, share log, and an on-demand job queue.
-- See docs/wulf-pulse-ticket-analyzer-prompt.md for the feature spec.

CREATE EXTENSION IF NOT EXISTS pgcrypto;

-- =============================================================================
-- analyzer_analyses
-- One row per completed (or failed) analysis; versioned per ticket_number.
-- =============================================================================
CREATE TABLE IF NOT EXISTS analyzer_analyses (
  id                          UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  ticket_number               TEXT NOT NULL,
  autotask_ticket_id          BIGINT NOT NULL,
  analysis_version            INT NOT NULL,
  content_hash_at_analysis    TEXT NOT NULL,
  triggered_by_user_id        TEXT REFERENCES "user"(id) ON DELETE SET NULL,
  triggered_at                TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  status                      TEXT NOT NULL DEFAULT 'pending'
                                CHECK (status IN ('pending','running','complete','failed')),
  completed_at                TIMESTAMPTZ,

  -- Model usage
  haiku_used                  BOOLEAN NOT NULL DEFAULT false,
  sonnet_used                 BOOLEAN NOT NULL DEFAULT false,
  opus_used                   BOOLEAN NOT NULL DEFAULT false,
  total_input_tokens          INT NOT NULL DEFAULT 0,
  total_output_tokens         INT NOT NULL DEFAULT 0,
  estimated_cost_usd          NUMERIC(10,4) NOT NULL DEFAULT 0,

  -- Structured output (each LLM stage's parsed JSON)
  summary                     TEXT,
  timeline                    JSONB,
  what_was_done               JSONB,
  what_should_have_been_done  JSONB,
  gaps                        JSONB,
  next_step                   TEXT,
  next_step_rationale         TEXT,
  post_resolution_analysis    TEXT,
  confidence_score            NUMERIC(3,2),
  needs_human_review          BOOLEAN NOT NULL DEFAULT false,
  human_review_reasons        JSONB,

  itglue_docs_referenced      JSONB NOT NULL DEFAULT '[]'::jsonb,

  -- Debugging / observability
  model_traces                JSONB,
  filtered_noise_count        INT NOT NULL DEFAULT 0,
  error_message               TEXT,

  CONSTRAINT analyzer_analyses_version_unique UNIQUE (ticket_number, analysis_version)
);

CREATE INDEX IF NOT EXISTS idx_analyzer_analyses_ticket_version
  ON analyzer_analyses (ticket_number, analysis_version DESC);

CREATE INDEX IF NOT EXISTS idx_analyzer_analyses_triggered_at
  ON analyzer_analyses (triggered_at DESC);

CREATE INDEX IF NOT EXISTS idx_analyzer_analyses_needs_review
  ON analyzer_analyses (needs_human_review)
  WHERE needs_human_review = true;

CREATE INDEX IF NOT EXISTS idx_analyzer_analyses_autotask_ticket_id
  ON analyzer_analyses (autotask_ticket_id);

COMMENT ON TABLE  analyzer_analyses IS 'Versioned AI analyses of Autotask tickets; one row per completed analysis run.';
COMMENT ON COLUMN analyzer_analyses.content_hash_at_analysis IS 'sha256 of canonical-JSON of (tagged_events, ticket_status, ticket_priority, queue) at analysis time. Used for idempotency.';
COMMENT ON COLUMN analyzer_analyses.filtered_noise_count IS 'Count of workflow-rule and notification-email notes stripped during pre-processing.';
COMMENT ON COLUMN analyzer_analyses.itglue_docs_referenced IS 'IDs/names of IT Glue docs cited; doc bodies are NEVER stored here (security).';

-- =============================================================================
-- analyzer_shares
-- Audit log of share-by-email events for any analysis.
-- =============================================================================
CREATE TABLE IF NOT EXISTS analyzer_shares (
  id                  UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  analysis_id         UUID NOT NULL REFERENCES analyzer_analyses(id) ON DELETE CASCADE,
  shared_by_user_id   TEXT NOT NULL REFERENCES "user"(id) ON DELETE CASCADE,
  shared_with_email   TEXT NOT NULL,
  note                TEXT,
  shared_at           TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  viewed_at           TIMESTAMPTZ
);

CREATE INDEX IF NOT EXISTS idx_analyzer_shares_analysis_id ON analyzer_shares (analysis_id);
CREATE INDEX IF NOT EXISTS idx_analyzer_shares_shared_by   ON analyzer_shares (shared_by_user_id);
CREATE INDEX IF NOT EXISTS idx_analyzer_shares_shared_at   ON analyzer_shares (shared_at DESC);

COMMENT ON TABLE analyzer_shares IS 'Audit log of analyses shared by email. Recipient domains validated against ALLOWED_SHARE_DOMAINS at write time.';

-- =============================================================================
-- analyzer_jobs
-- On-demand pipeline queue. A worker initialised at server start polls this table.
-- =============================================================================
CREATE TABLE IF NOT EXISTS analyzer_jobs (
  id                    UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  ticket_number         TEXT NOT NULL,
  queued_by_user_id     TEXT REFERENCES "user"(id) ON DELETE SET NULL,
  status                TEXT NOT NULL DEFAULT 'queued'
                          CHECK (status IN ('queued','fetching','triaging','itglue','analyzing','deep_review','complete','failed')),
  result_analysis_id    UUID REFERENCES analyzer_analyses(id) ON DELETE SET NULL,
  queued_at             TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  started_at            TIMESTAMPTZ,
  finished_at           TIMESTAMPTZ,
  error_message         TEXT
);

CREATE INDEX IF NOT EXISTS idx_analyzer_jobs_status_queued
  ON analyzer_jobs (status, queued_at)
  WHERE status IN ('queued','fetching','triaging','itglue','analyzing','deep_review');

CREATE INDEX IF NOT EXISTS idx_analyzer_jobs_ticket_number ON analyzer_jobs (ticket_number);
CREATE INDEX IF NOT EXISTS idx_analyzer_jobs_queued_at     ON analyzer_jobs (queued_at DESC);

COMMENT ON TABLE analyzer_jobs IS 'On-demand analyzer pipeline jobs. Polled by a single worker that initialises at server start.';
