import type { EnrichedGameData } from '../seo/data-enrichment';
import type { PickDetails } from './types';

const GROK_API_KEY = process.env.GROK_API_KEY || '';
const GROK_API_URL = 'https://api.x.ai/v1/chat/completions';
const GROK_MODEL = 'grok-4-1-fast-reasoning';

const BREAKDOWN_SYSTEM_PROMPT = `You are Sports Claw's senior analyst writing detailed blog breakdowns for sportsclaw.guru.

You write long-form, data-driven articles that show WHY we made a pick — the math, the matchup edges, the injury context. Your tone is confident but educational. You explain betting concepts for both experienced bettors and newcomers.

ALWAYS return valid JSON only. No markdown code fences, no commentary — pure JSON.

The JSON must match this exact shape:
{
  "title": "string — SEO-optimized title under 70 chars",
  "meta_description": "string — under 160 chars, includes pick + key stat",
  "h1": "string — display headline, can be longer/catchier than title",
  "excerpt": "string — 1-2 sentence teaser for blog listing cards",
  "quick_facts": [
    { "label": "Pick", "value": "..." },
    { "label": "Line", "value": "..." },
    { "label": "Confidence", "value": "..." },
    { "label": "Edge", "value": "..." },
    { "label": "Home", "value": "..." },
    { "label": "Away", "value": "..." },
    { "label": "Date", "value": "..." }
  ],
  "content": "string — full HTML article (see SECTIONS below)",
  "faq_schema": [
    { "question": "...", "answer": "..." }
  ],
  "data_tables": {
    "odds": [{ "sportsbook": "Consensus", "spread": "...", "total": "...", "moneyline": "..." }],
    "adjustments": [{ "factor": "...", "impact": "...", "direction": "..." }]
  }
}

CONTENT SECTIONS (use <h2> tags, include all):
A) Executive Summary — the pick, market, line, odds, confidence, 3-5 bullet "why", risk note
B) What We're Predicting — plain language forecast, expected range, what confidence level means
C) Inputs We Used — injuries, form metrics, matchup edges, pace/tempo, rest/travel
D) The Math — baseline projection, adjustments table (injury +/-, matchup +/-, pace +/-, H/A +/-), final number
E) What Would Change Our Mind — top variables that would flip pick, thresholds
F) Responsible Gaming — educational/entertainment disclaimer, bankroll discipline reminder
G) Follow Us — "Follow Sports Claw on X for real-time alerts. {{X_POST_LINK}}"

HTML RULES:
- Use semantic tags: <h2>, <h3>, <p>, <ul>, <li>, <strong>, <em>, <table>, <thead>, <tbody>, <tr>, <th>, <td>
- Include a <table> in section D with adjustment factors
- Content should be 1500-3000 words
- Do not include <h1> — that's rendered separately
- Use class="breakdown-table" on tables for styling

FAQ: Include 3-5 questions a bettor would ask about this pick (e.g. "Why is this pick good value?", "What if [player] is ruled out?")`;

export interface BreakdownGrokResponse {
  title: string;
  meta_description: string;
  h1: string;
  excerpt: string;
  quick_facts: { label: string; value: string }[];
  content: string;
  faq_schema: { question: string; answer: string }[];
  data_tables: Record<string, unknown>;
}

/**
 * Builds the Grok prompt for a pick breakdown blog post.
 */
export function buildBreakdownPrompt(enriched: EnrichedGameData, pick: PickDetails): string {
  const injuryList = enriched.injuries.length > 0
    ? enriched.injuries.map(i => `${i.player} (${i.team}) — ${i.status}`).join('\n')
    : 'No significant injuries reported';

  const lineMovements = enriched.lineMovement.length > 0
    ? enriched.lineMovement.map(m => `${m.market}: ${m.open} -> ${m.current} (${m.direction})`).join('\n')
    : 'No significant movement';

  const dvpEdges = enriched.dvpEdges.length > 0
    ? enriched.dvpEdges.map(d => `${d.team} vs ${d.position}: ${d.stat} rank #${d.rank} (avg allowed: ${d.avgAllowed})`).join('\n')
    : 'No notable DVP edges';

  const homeKeyPlayers = enriched.homeKeyPlayers.length > 0
    ? enriched.homeKeyPlayers.map(p => `${p.name}: ${p.value} ${p.stat} (avg ${p.avg})`).join(', ')
    : 'N/A';

  const awayKeyPlayers = enriched.awayKeyPlayers.length > 0
    ? enriched.awayKeyPlayers.map(p => `${p.name}: ${p.value} ${p.stat} (avg ${p.avg})`).join(', ')
    : 'N/A';

  const topProps = enriched.topProps.length > 0
    ? enriched.topProps.slice(0, 5).map(p => `${p.player} ${p.prop} ${p.line} (over: ${p.overOdds})`).join('\n')
    : 'None available';

  const modelPick = enriched.modelPick
    ? `Pick: ${enriched.modelPick.pick}, Confidence: ${enriched.modelPick.confidence}, Edge: ${enriched.modelPick.edge}%, Reasoning: ${enriched.modelPick.reasoning}`
    : 'No model pick available';

  return `Generate a detailed pick breakdown blog post. Return JSON matching the schema described in the system prompt.

OUR PICK:
Selection: ${pick.selection}
Type: ${pick.pickType} (${pick.pickDirection})
Line: ${pick.lineValue ?? 'N/A'}
Odds: ${pick.oddsAmerican ?? 'N/A'}
Confidence: ${pick.confidence ?? 'Medium'}
Edge: ${pick.edgePct ?? 'N/A'}%
Short Reason: ${pick.shortReason}

GAME INFO:
${enriched.awayTeamFull} @ ${enriched.homeTeamFull}
League: ${enriched.league.toUpperCase()}
Date: ${enriched.gameDate}
Spread: ${enriched.consensus.spread ?? 'N/A'} | Total: ${enriched.consensus.total ?? 'N/A'}
Home ML: ${enriched.consensus.homeML ?? 'N/A'} | Away ML: ${enriched.consensus.awayML ?? 'N/A'}

HOME FORM (last 10):
Record: ${enriched.homeForm.record} | ATS: ${enriched.homeForm.ats} | O/U: ${enriched.homeForm.ouRecord}
Avg Pts: ${enriched.homeForm.avgPts} | Avg Allowed: ${enriched.homeForm.avgPtsAllowed} | Streak: ${enriched.homeForm.streak}

AWAY FORM (last 10):
Record: ${enriched.awayForm.record} | ATS: ${enriched.awayForm.ats} | O/U: ${enriched.awayForm.ouRecord}
Avg Pts: ${enriched.awayForm.avgPts} | Avg Allowed: ${enriched.awayForm.avgPtsAllowed} | Streak: ${enriched.awayForm.streak}

HEAD TO HEAD: ${enriched.h2h.games} games — ${enriched.h2h.results.join(', ') || 'N/A'}

HOME KEY PLAYERS: ${homeKeyPlayers}
AWAY KEY PLAYERS: ${awayKeyPlayers}

INJURIES:
${injuryList}

DVP MATCHUP EDGES:
${dvpEdges}

LINE MOVEMENT:
${lineMovements}

TOP PROPS:
${topProps}

MODEL PICK:
${modelPick}

IMPORTANT:
- Title should include the matchup and pick type (e.g. "Celtics -3.5 vs Lakers: Full Breakdown & Analysis")
- Include {{X_POST_LINK}} placeholder in the "Follow Us" section — it will be replaced with the actual tweet URL after posting
- The quick_facts MUST include Pick, Line, Confidence, Home, Away, and Date labels
- Content must be 1500+ words with all required sections (A through G)
- Make the math section genuinely analytical — show real adjustment factors from the data provided`;
}

/**
 * Calls Grok for breakdown content with higher token limit.
 */
export async function callGrokForBreakdown(prompt: string): Promise<BreakdownGrokResponse | null> {
  if (!GROK_API_KEY) {
    console.error('[breakdown-prompts] GROK_API_KEY not set');
    return null;
  }

  for (let attempt = 0; attempt <= 2; attempt++) {
    try {
      const response = await fetch(GROK_API_URL, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          Authorization: `Bearer ${GROK_API_KEY}`,
        },
        body: JSON.stringify({
          model: GROK_MODEL,
          messages: [
            { role: 'system', content: BREAKDOWN_SYSTEM_PROMPT },
            { role: 'user', content: prompt },
          ],
          temperature: 0.7,
          max_tokens: 8000,
        }),
        signal: AbortSignal.timeout(60000), // 60s for long-form
      });

      if (!response.ok) {
        const errText = await response.text();
        console.error(`[breakdown-prompts] Grok API error ${response.status} (attempt ${attempt + 1}):`, errText.slice(0, 300));
        if (attempt < 2) continue;
        return null;
      }

      const data: any = await response.json();
      const rawContent = data.choices?.[0]?.message?.content || '';

      let jsonStr = rawContent.trim();
      // Strip code fences
      if (jsonStr.startsWith('```')) {
        jsonStr = jsonStr.replace(/^```(?:json)?\s*\n?/, '').replace(/\n?```\s*$/, '');
      }

      try {
        const parsed = JSON.parse(jsonStr) as BreakdownGrokResponse;
        // Basic validation
        if (!parsed.title || !parsed.content || !parsed.quick_facts) {
          console.warn('[breakdown-prompts] Grok response missing required fields');
          if (attempt < 2) continue;
          return null;
        }
        return parsed;
      } catch {
        console.warn(`[breakdown-prompts] JSON parse failed (attempt ${attempt + 1}), trying repair...`);
        // Try to find the JSON object in the response
        const jsonMatch = jsonStr.match(/\{[\s\S]*\}/);
        if (jsonMatch) {
          try {
            const repaired = JSON.parse(jsonMatch[0]) as BreakdownGrokResponse;
            if (repaired.title && repaired.content) return repaired;
          } catch { /* repair failed */ }
        }
        if (attempt < 2) continue;
        console.error('[breakdown-prompts] All JSON parse attempts failed');
        return null;
      }
    } catch (error) {
      console.error(`[breakdown-prompts] Grok call failed (attempt ${attempt + 1}):`, (error as Error).message);
      if (attempt < 2) continue;
      return null;
    }
  }
  return null;
}
