"""
DB Schemas — Centralized schema definitions for Report Agent SQL generation.

Contains detailed column descriptions, all analysis groups, and
ready-to-use SQL examples for all tables the agent can query.
This ensures the LLM generates correct SQL (right column names, types, filters).

Imported by: agent/report_agent/prompts/agent_prompt.py
             agent/report_agent/prompts/follow_up_prompt.py
"""

# ═══════════════════════════════════════════════════════════════════
# TABLE 1: LANGFUSE TRACES (StarRocks)
# Mỗi row = 1 trace (1 lượt user gửi tin nhắn → AI trả lời)
# ═══════════════════════════════════════════════════════════════════
LANGFUSE_TABLE = "analytic.chatbot_rsa_trace_event_detail"

LANGFUSE_SCHEMA = f"""
## Table: {LANGFUSE_TABLE} (StarRocks — Langfuse Chatbot Traces)
Each row = 1 chatbot interaction (user sends message → AI responds).

### Identity & Session:
- trace_id (VARCHAR) — Unique ID per trace
- project_id (VARCHAR) — Langfuse project ID (partition key)
- org_id (VARCHAR) — Organization ID (partition key)
- project_name (VARCHAR) — Project name (e.g. "canifa-chatbot")
- org_name (VARCHAR) — Organization name
- session_id (VARCHAR) — Chat session ID. Multiple traces share 1 session
- customer_id (VARCHAR) — Customer ID (if logged in, else NULL)
- device_id (VARCHAR) — Browser fingerprint / device ID

### Performance:
- trace_latency (DECIMAL) — Total AI processing time in SECONDS
- user_latency (DECIMAL) — User-perceived latency in SECONDS (includes network)

### Chat Content:
- input_query (VARCHAR) — User's message text
- output_ai_response (VARCHAR) — AI's response text

### Cost (USD):
- input_cost (DECIMAL) — Input token cost in USD
- output_cost (DECIMAL) — Output token cost in USD
- total_cost (DECIMAL) — Total cost = input_cost + output_cost (USD)

### Model:
- model_name (VARCHAR) — LLM model used (e.g. 'gpt-5.2-codex', 'gemini-3.1-flash-lite')

### Error Tracking:
- total_obs (BIGINT) — Number of observations (processing steps) in this trace
- total_obs_error (BIGINT) — Number of observations that errored
- nb_generation_error (BIGINT) — Number of LLM generation errors

### User Type (BOOLEAN — use TRUE/FALSE, NOT 1/0):
- is_guest (BOOLEAN) — TRUE = anonymous guest, FALSE = not guest
- is_user (BOOLEAN) — TRUE = logged-in user, FALSE = not logged-in
  ⚠️ CRITICAL: Use `WHERE is_guest = TRUE` or `CASE WHEN is_guest THEN 'guest'`, NEVER `is_guest = 1`

### Timestamps:
- traced_at (DATETIME) — When the interaction happened (primary time column for analysis)
- created_at (DATETIME) — Record creation time
- updated_at (DATETIME) — Record last update time
- refreshed_at (DATETIME) — Data refresh time from Langfuse

---
## ANALYSIS GROUPS & READY-TO-USE SQL EXAMPLES for {LANGFUSE_TABLE}:

### 💰 Group 1: Cost & Economics
```sql
-- 1.1 Total cost today
SELECT DATE(traced_at) AS ngay, COUNT(*) AS total_traces,
  ROUND(SUM(total_cost),4) AS total_cost_usd,
  ROUND(AVG(total_cost),6) AS avg_cost_per_trace,
  ROUND(SUM(input_cost),4) AS input_cost_usd,
  ROUND(SUM(output_cost),4) AS output_cost_usd
FROM {LANGFUSE_TABLE}
WHERE DATE(traced_at) = CURDATE()
GROUP BY ngay LIMIT 5;

-- 1.2 Cost by model (which model costs most?)
SELECT model_name, COUNT(*) AS traces,
  ROUND(SUM(total_cost),4) AS total_cost_usd,
  ROUND(AVG(total_cost),6) AS avg_cost_per_trace,
  ROUND(SUM(total_cost)*100.0 / (SELECT SUM(total_cost) FROM {LANGFUSE_TABLE} WHERE DATE(traced_at) = CURDATE()), 1) AS cost_pct
FROM {LANGFUSE_TABLE}
WHERE DATE(traced_at) = CURDATE()
GROUP BY model_name
ORDER BY total_cost_usd DESC LIMIT 10;

-- 1.3 Cost trend over last 7 days (for time-series chart)
SELECT DATE(traced_at) AS ngay, COUNT(*) AS traces,
  ROUND(SUM(total_cost),4) AS total_cost,
  ROUND(AVG(total_cost),6) AS avg_cost
FROM {LANGFUSE_TABLE}
WHERE traced_at >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)
GROUP BY ngay ORDER BY ngay LIMIT 20;

-- 1.4 Input vs Output cost comparison
SELECT
  ROUND(SUM(input_cost),4) AS total_input_cost,
  ROUND(SUM(output_cost),4) AS total_output_cost,
  ROUND(SUM(input_cost)*100.0/NULLIF(SUM(total_cost),0), 1) AS input_pct,
  ROUND(SUM(output_cost)*100.0/NULLIF(SUM(total_cost),0), 1) AS output_pct
FROM {LANGFUSE_TABLE}
WHERE DATE(traced_at) = CURDATE() LIMIT 1;
```

### ⚡ Group 2: Performance & Latency
```sql
-- 2.1 Average latency today
SELECT COUNT(*) AS traces,
  ROUND(AVG(trace_latency),2) AS avg_latency_s,
  ROUND(MIN(trace_latency),2) AS min_latency_s,
  ROUND(MAX(trace_latency),2) AS max_latency_s,
  ROUND(AVG(user_latency),2) AS avg_user_latency_s
FROM {LANGFUSE_TABLE}
WHERE DATE(traced_at) = CURDATE() LIMIT 1;

-- 2.2 Latency by model
SELECT model_name, COUNT(*) AS traces,
  ROUND(AVG(trace_latency),2) AS avg_latency_s,
  ROUND(MAX(trace_latency),2) AS max_latency_s
FROM {LANGFUSE_TABLE}
WHERE DATE(traced_at) = CURDATE()
GROUP BY model_name ORDER BY avg_latency_s DESC LIMIT 10;

-- 2.3 Latency by hour (peak hours analysis)
SELECT HOUR(traced_at) AS gio, COUNT(*) AS traces,
  ROUND(AVG(trace_latency),2) AS avg_latency_s
FROM {LANGFUSE_TABLE}
WHERE DATE(traced_at) = CURDATE()
GROUP BY gio ORDER BY gio LIMIT 24;

-- 2.4 Slow traces (>10s) — how many?
SELECT COUNT(*) AS slow_traces,
  ROUND(COUNT(*)*100.0 / (SELECT COUNT(*) FROM {LANGFUSE_TABLE} WHERE DATE(traced_at) = CURDATE()), 1) AS slow_pct
FROM {LANGFUSE_TABLE}
WHERE DATE(traced_at) = CURDATE() AND trace_latency > 10 LIMIT 1;
```

### 🔴 Group 3: Errors & Stability
```sql
-- 3.1 Error rate today
SELECT COUNT(*) AS total_traces,
  SUM(CASE WHEN total_obs_error > 0 THEN 1 ELSE 0 END) AS error_traces,
  ROUND(SUM(CASE WHEN total_obs_error > 0 THEN 1 ELSE 0 END)*100.0/COUNT(*), 1) AS error_rate_pct,
  SUM(nb_generation_error) AS total_gen_errors
FROM {LANGFUSE_TABLE}
WHERE DATE(traced_at) = CURDATE() LIMIT 1;

-- 3.2 Error rate by model
SELECT model_name, COUNT(*) AS traces,
  SUM(CASE WHEN total_obs_error > 0 THEN 1 ELSE 0 END) AS errors,
  ROUND(SUM(CASE WHEN total_obs_error > 0 THEN 1 ELSE 0 END)*100.0/COUNT(*), 1) AS error_pct
FROM {LANGFUSE_TABLE}
WHERE DATE(traced_at) = CURDATE()
GROUP BY model_name ORDER BY error_pct DESC LIMIT 10;

-- 3.3 Error trend over 7 days
SELECT DATE(traced_at) AS ngay,
  COUNT(*) AS total,
  SUM(CASE WHEN total_obs_error > 0 THEN 1 ELSE 0 END) AS errors,
  ROUND(SUM(CASE WHEN total_obs_error > 0 THEN 1 ELSE 0 END)*100.0/COUNT(*), 1) AS error_pct
FROM {LANGFUSE_TABLE}
WHERE traced_at >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)
GROUP BY ngay ORDER BY ngay LIMIT 20;
```

### 👥 Group 4: User Segmentation
```sql
-- 4.1 Guest vs User breakdown
SELECT
  CASE WHEN is_guest THEN 'Guest' WHEN is_user THEN 'User' ELSE 'Unknown' END AS user_type,
  COUNT(*) AS traces,
  COUNT(DISTINCT device_id) AS unique_devices,
  ROUND(SUM(total_cost),4) AS total_cost,
  ROUND(AVG(total_cost),6) AS avg_cost,
  ROUND(AVG(trace_latency),2) AS avg_latency
FROM {LANGFUSE_TABLE}
WHERE DATE(traced_at) = CURDATE()
GROUP BY user_type LIMIT 5;

-- 4.2 Unique users & sessions per day
SELECT DATE(traced_at) AS ngay,
  COUNT(DISTINCT device_id) AS unique_users,
  COUNT(DISTINCT session_id) AS unique_sessions,
  COUNT(*) AS total_traces,
  ROUND(COUNT(*)*1.0/NULLIF(COUNT(DISTINCT session_id),0), 1) AS traces_per_session
FROM {LANGFUSE_TABLE}
WHERE traced_at >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)
GROUP BY ngay ORDER BY ngay LIMIT 20;

-- 4.3 Top heavy users (who chats the most?)
SELECT COALESCE(customer_id, device_id) AS user_id,
  CASE WHEN is_user THEN 'User' ELSE 'Guest' END AS user_type,
  COUNT(*) AS trace_count,
  ROUND(SUM(total_cost),4) AS total_cost
FROM {LANGFUSE_TABLE}
WHERE DATE(traced_at) = CURDATE()
GROUP BY user_id, user_type
ORDER BY trace_count DESC LIMIT 10;
```

### 💬 Group 5: Chat Content Analysis
```sql
-- 5.1 Message length statistics
SELECT
  ROUND(AVG(LENGTH(input_query)),0) AS avg_question_length,
  ROUND(AVG(LENGTH(output_ai_response)),0) AS avg_answer_length,
  ROUND(AVG(LENGTH(output_ai_response))*1.0/NULLIF(AVG(LENGTH(input_query)),0), 1) AS answer_to_question_ratio
FROM {LANGFUSE_TABLE}
WHERE DATE(traced_at) = CURDATE() AND input_query IS NOT NULL LIMIT 1;

-- 5.2 Sample recent conversations (for topic analysis)
SELECT traced_at, LEFT(input_query, 150) AS question_preview,
  LEFT(output_ai_response, 150) AS answer_preview,
  model_name, ROUND(trace_latency,1) AS latency_s
FROM {LANGFUSE_TABLE}
WHERE DATE(traced_at) = CURDATE() AND input_query IS NOT NULL
ORDER BY traced_at DESC LIMIT 10;

-- 5.3 Empty/null responses
SELECT COUNT(*) AS total,
  SUM(CASE WHEN input_query IS NULL OR input_query = '' THEN 1 ELSE 0 END) AS empty_questions,
  SUM(CASE WHEN output_ai_response IS NULL OR output_ai_response = '' THEN 1 ELSE 0 END) AS empty_answers
FROM {LANGFUSE_TABLE}
WHERE DATE(traced_at) = CURDATE() LIMIT 1;
```
"""

# ═══════════════════════════════════════════════════════════════════
# TABLE 2: CLEVERTAP EVENTS (StarRocks)
# Mỗi row = 1 event trong 1 session (filter event_name = 'Chatbot Viewed')
# ═══════════════════════════════════════════════════════════════════
CLEVERTAP_TABLE = "analytic.clevertap_event_by_session"

CLEVERTAP_SCHEMA = f"""
## Table: {CLEVERTAP_TABLE} (StarRocks — CleverTap User Behavior)
Frontend event tracking. Each row = 1 event type in 1 user session.
Filter `WHERE event_name = 'Chatbot Viewed'` to get chatbot usage events.

### Identity:
- dwh_clevertap_profile_id (INT) — CleverTap user profile ID (partition key)
- event_name (VARCHAR) — Event name (partition key). Use 'Chatbot Viewed' for chatbot
- session_id (INT) — Web/app session ID (partition key)

### Timing:
- event_date_group (DATE) — Date of the event
- event_first_time (DATETIME) — First occurrence of event in this session
- event_last_time (DATETIME) — Last occurrence of event in this session

### Metrics:
- nb_event (BIGINT) — Number of times event fired in this session
- surfing_seconds (DECIMAL) — Browsing duration in this session (seconds)

### Platform:
- platform (ARRAY<VARCHAR>) — Platforms (web, app, etc.)
- session_platform (ARRAY<VARCHAR>) — Session-level platform
- platform_os (VARCHAR) — OS (iOS, Android, Windows, etc.)

### Context:
- list_product (ARRAY<VARCHAR>) — Products user viewed in this session
- event_props (JSON) — Detailed event properties
- device_id (ARRAY<VARCHAR>) — Device IDs (array, use array_contains() to match)
- page_url (ARRAY<VARCHAR>) — URLs user visited

---
## ANALYSIS GROUPS & READY-TO-USE SQL EXAMPLES for {CLEVERTAP_TABLE}:

### 📱 Group 6: Frontend User Behavior
```sql
-- 6.1 Daily unique chatbot users
SELECT event_date_group AS ngay,
  COUNT(DISTINCT dwh_clevertap_profile_id) AS unique_users,
  COUNT(DISTINCT session_id) AS unique_sessions,
  SUM(nb_event) AS total_chatbot_opens
FROM {CLEVERTAP_TABLE}
WHERE event_name = 'Chatbot Viewed'
  AND event_date_group = CURDATE()
GROUP BY ngay LIMIT 5;

-- 6.2 Chatbot users trend (7 days)
SELECT event_date_group AS ngay,
  COUNT(DISTINCT dwh_clevertap_profile_id) AS unique_users,
  SUM(nb_event) AS total_opens
FROM {CLEVERTAP_TABLE}
WHERE event_name = 'Chatbot Viewed'
  AND event_date_group >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)
GROUP BY ngay ORDER BY ngay LIMIT 20;

-- 6.3 Platform/OS breakdown
SELECT platform_os, COUNT(DISTINCT dwh_clevertap_profile_id) AS users,
  COUNT(DISTINCT session_id) AS sessions,
  ROUND(AVG(surfing_seconds),0) AS avg_browsing_secs
FROM {CLEVERTAP_TABLE}
WHERE event_name = 'Chatbot Viewed'
  AND event_date_group = CURDATE()
GROUP BY platform_os ORDER BY users DESC LIMIT 10;

-- 6.4 Average browsing time before opening chatbot
SELECT
  ROUND(AVG(surfing_seconds),0) AS avg_surfing_secs,
  ROUND(MIN(surfing_seconds),0) AS min_surfing_secs,
  ROUND(MAX(surfing_seconds),0) AS max_surfing_secs,
  ROUND(AVG(nb_event),1) AS avg_chatbot_opens_per_session
FROM {CLEVERTAP_TABLE}
WHERE event_name = 'Chatbot Viewed'
  AND event_date_group = CURDATE() LIMIT 1;

-- 6.5 Peak hours: when do users open chatbot?
SELECT HOUR(event_first_time) AS gio,
  COUNT(DISTINCT dwh_clevertap_profile_id) AS users,
  SUM(nb_event) AS total_opens
FROM {CLEVERTAP_TABLE}
WHERE event_name = 'Chatbot Viewed'
  AND event_date_group = CURDATE()
GROUP BY gio ORDER BY gio LIMIT 24;
```

### 🔗 Group 7: Cross-Reference (Join Langfuse + CleverTap)
```sql
-- 7.1 Chatbot bounce rate: users who OPENED chatbot but did NOT chat
-- (CleverTap has event, Langfuse has no trace for that device)
SELECT
  ct_users.total_opened AS users_opened_chatbot,
  lf_users.total_chatted AS users_actually_chatted,
  ct_users.total_opened - COALESCE(lf_users.total_chatted, 0) AS bounced,
  ROUND((ct_users.total_opened - COALESCE(lf_users.total_chatted, 0))*100.0/ct_users.total_opened, 1) AS bounce_rate_pct
FROM
  (SELECT COUNT(DISTINCT dwh_clevertap_profile_id) AS total_opened
   FROM {CLEVERTAP_TABLE}
   WHERE event_name = 'Chatbot Viewed' AND event_date_group = CURDATE()) ct_users,
  (SELECT COUNT(DISTINCT device_id) AS total_chatted
   FROM {LANGFUSE_TABLE}
   WHERE DATE(traced_at) = CURDATE()) lf_users
LIMIT 1;

-- 7.2 Platform performance: latency by OS
-- (requires device_id join — use subquery approach)
SELECT lf.platform_group, COUNT(*) AS traces,
  ROUND(AVG(lf.trace_latency),2) AS avg_latency,
  ROUND(SUM(lf.total_cost),4) AS total_cost
FROM (
  SELECT t.trace_latency, t.total_cost, t.device_id,
    COALESCE(
      (SELECT ct.platform_os FROM {CLEVERTAP_TABLE} ct
       WHERE event_name = 'Chatbot Viewed'
         AND array_contains(ct.device_id, t.device_id)
       LIMIT 1),
      'Unknown'
    ) AS platform_group
  FROM {LANGFUSE_TABLE} t
  WHERE DATE(t.traced_at) = CURDATE()
) lf
GROUP BY lf.platform_group ORDER BY traces DESC LIMIT 10;
```
"""
