import { User } from '../models/user';

const SGO_API_KEY: string = process.env.SGO_API_KEY || '';
const SGO_BASE_URL = 'https://api.sportsgameodds.com/v2';

if (!SGO_API_KEY) {
  console.warn('⚠️ SGO_API_KEY not set — sports data queries will be unavailable');
}

interface QueryResult {
  type: string;
  message: string;
}

export async function querySportsData(query: string, user: User): Promise<QueryResult> {
  if (!SGO_API_KEY) {
    return { type: 'error', message: 'Sports data service is currently unavailable. Please try again later.' };
  }

  const queryLower = query.toLowerCase();
  
  // Detect query type
  if (queryLower.includes('prop') || containsPlayerName(queryLower)) {
    return handlePlayerQuery(queryLower, user);
  }
  
  if (queryLower.includes('odds') || queryLower.includes('spread') || queryLower.includes('total') || queryLower.includes('line')) {
    return handleOddsQuery(queryLower);
  }
  
  if (queryLower.includes(' vs ') || queryLower.includes(' @ ')) {
    return handleMatchupQuery(queryLower);
  }
  
  // Default to odds lookup
  return handleOddsQuery(queryLower);
}

function containsPlayerName(query: string): boolean {
  // Common player name patterns
  const patterns = [
    /\b(lebron|curry|durant|giannis|jokic|tatum|doncic|embiid)\b/i,
    /\b(mahomes|allen|burrow|jackson|herbert|hurts)\b/i,
    /\b(ohtani|judge|soto|acuna|betts)\b/i,
  ];
  return patterns.some(p => p.test(query));
}

async function handleOddsQuery(query: string): Promise<QueryResult> {
  const league = detectLeague(query);
  
  try {
    const response = await fetch(
      `${SGO_BASE_URL}/events?leagueID=${league}&oddsAvailable=true&limit=10`,
      { headers: { 'x-api-key': SGO_API_KEY } }
    );
    
    const data = await response.json() as { data?: any[] };
    const events = data.data || [];
    
    if (events.length === 0) {
      return {
        type: 'odds',
        message: `No ${league} games with odds found right now.`,
      };
    }
    
    const emoji = getLeagueEmoji(league);
    let message = `${emoji} *${league} Odds*\n\n`;
    
    for (const event of events.slice(0, 5)) {
      const home = event.teams?.home?.names?.short || 'Home';
      const away = event.teams?.away?.names?.short || 'Away';
      const time = formatGameTime(event.status?.startsAt);
      
      const mlHome = event.odds?.['points-home-game-ml-home']?.fairOdds || '-';
      const mlAway = event.odds?.['points-away-game-ml-away']?.fairOdds || '-';
      const spread = event.odds?.['points-home-game-sp-home']?.fairSpread || '-';
      const ouData = event.odds?.['points-all-game-ou-over']; const total = ouData?.fairOverUnder || ouData?.bookOverUnder || '-';
      
      message += `*${away} @ ${home}*\n`;
      message += `⏰ ${time}\n`;
      message += `ML: ${mlAway} / ${mlHome}\n`;
      message += `Spread: ${spread}\n`;
      message += `O/U: ${total}\n\n`;
    }
    
    return { type: 'odds', message };
    
  } catch (error) {
    console.error('Odds query error:', error);
    return {
      type: 'odds',
      message: 'Unable to fetch odds right now. Try again shortly.',
    };
  }
}

const SPORTS_TERMS = new Set([
  'nba odds', 'nfl odds', 'mlb odds', 'nhl odds',
  'over under', 'point spread', 'money line', 'moneyline odds',
  'player props', 'game time', 'home team', 'away team',
  'first half', 'second half', 'full game', 'live odds',
  'total points', 'passing yards', 'rushing yards', 'receiving yards',
  'odds tonight', 'odds today', 'odds tomorrow', 'game odds',
  'spread today', 'spread tonight', 'total today', 'total tonight',
  'props today', 'props tonight', 'line today', 'line tonight',
]);

async function handlePlayerQuery(query: string, user: User): Promise<QueryResult> {
  // Check if user has access to props
  if (user.plan === 'free') {
    return {
      type: 'prop',
      message: `🔒 *Player Props - Pro Feature*\n\n` +
        `Unlock player prop analysis:\n\n` +
        `✅ L10 game averages\n` +
        `✅ Edge calculations vs line\n` +
        `✅ Defensive matchup ratings\n` +
        `✅ Injury-adjusted projections\n\n` +
        `💰 *$30/month* or *$9/week*\n\n` +
        `👉 Upgrade now:\nhttps://sportsclaw.guru/signup?plan=monthly`,
    };
  }

  // Strip common keywords before extracting player name
  const STRIP_WORDS = /\b(nba|nfl|mlb|nhl|ufc|ncaa|odds|spread|total|line|prop|props|points|rebounds|assists|yards|passing|rushing|receiving|over|under|today|tonight|tomorrow)\b/gi;
  const cleaned = query.replace(STRIP_WORDS, '').replace(/\s+/g, ' ').trim();
  const twoWordMatch = cleaned.match(/\b([a-z]+ [a-z]+)\b/i);
  const playerMatch = twoWordMatch && !SPORTS_TERMS.has(twoWordMatch[1].toLowerCase())
    ? twoWordMatch
    : null;

  if (!playerMatch) {
    return {
      type: 'prop',
      message: 'Please specify a player name. Example: `lebron james points`',
    };
  }

  const playerName = playerMatch[1];
  const league = detectLeague(query);

  try {
    const response = await fetch(
      `${SGO_BASE_URL}/odds?leagueID=${league}&oddsType=player&search=${encodeURIComponent(playerName)}&limit=5`,
      { headers: { 'x-api-key': SGO_API_KEY } }
    );

    const data = await response.json() as { data?: any[] };
    const props = data.data || [];

    if (props.length === 0) {
      return {
        type: 'prop',
        message: `No prop data currently available for *${playerName.split(' ').map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(' ')}*. Try checking back closer to game time.`,
      };
    }

    const displayName = playerName.split(' ').map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(' ');
    let message = `📊 *${displayName} - Props*\n\n`;

    for (const prop of props.slice(0, 3)) {
      const line = prop.fairSpread ?? prop.spread ?? '-';
      const overOdds = prop.fairOdds ?? prop.overOdds ?? '-';
      const underOdds = prop.underOdds ?? '-';
      const market = prop.marketName ?? prop.oddID ?? 'Prop';

      message += `*${market}*\n`;
      message += `Line: ${line}\n`;
      message += `Over: ${overOdds} | Under: ${underOdds}\n\n`;
    }

    message += `_Data from SportsGameOdds_`;
    return { type: 'prop', message };

  } catch (error) {
    console.error('Player props query error:', error);
    return {
      type: 'prop',
      message: `No prop data currently available for *${playerName.split(' ').map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(' ')}*. Try checking back closer to game time.`,
    };
  }
}

async function handleMatchupQuery(query: string): Promise<QueryResult> {
  // Extract teams
  const teams = query.split(/\s+(?:vs|@)\s+/i);

  if (teams.length < 2) {
    return {
      type: 'matchup',
      message: 'Please specify two teams. Example: `celtics vs lakers`',
    };
  }

  const team1 = teams[0].trim().toLowerCase();
  const team2 = teams[1].trim().toLowerCase();
  const league = detectLeague(query);
  const emoji = getLeagueEmoji(league);

  try {
    const response = await fetch(
      `${SGO_BASE_URL}/events?leagueID=${league}&oddsAvailable=true&limit=20`,
      { headers: { 'x-api-key': SGO_API_KEY } }
    );

    const data = await response.json() as { data?: any[] };
    const events = data.data || [];

    const matchup = events.find((event: any) => {
      const homeShort = (event.teams?.home?.names?.short || '').toLowerCase();
      const homeLong = (event.teams?.home?.names?.long || '').toLowerCase();
      const awayShort = (event.teams?.away?.names?.short || '').toLowerCase();
      const awayLong = (event.teams?.away?.names?.long || '').toLowerCase();

      const matchesTeam = (team: string, short: string, long: string) =>
        short.includes(team) || long.includes(team) || team.includes(short);

      return (matchesTeam(team1, homeShort, homeLong) && matchesTeam(team2, awayShort, awayLong)) ||
             (matchesTeam(team2, homeShort, homeLong) && matchesTeam(team1, awayShort, awayLong));
    });

    if (!matchup) {
      return {
        type: 'matchup',
        message: `No upcoming matchup found between *${team1}* and *${team2}*.`,
      };
    }

    const home = matchup.teams?.home?.names?.short || 'Home';
    const away = matchup.teams?.away?.names?.short || 'Away';
    const time = formatGameTime(matchup.status?.startsAt);

    const mlHome = matchup.odds?.['points-home-game-ml-home']?.fairOdds || '-';
    const mlAway = matchup.odds?.['points-away-game-ml-away']?.fairOdds || '-';
    const spread = matchup.odds?.['points-home-game-sp-home']?.fairSpread || '-';
    const muOuData = matchup.odds?.['points-all-game-ou-over']; const total = muOuData?.fairOverUnder || muOuData?.bookOverUnder || '-';

    const message = `${emoji} *${away} @ ${home}*\n` +
      `⏰ ${time}\n\n` +
      `ML: ${mlAway} / ${mlHome}\n` +
      `Spread: ${spread}\n` +
      `O/U: ${total}\n\n` +
      `_Data from SportsGameOdds_`;

    return { type: 'matchup', message };

  } catch (error) {
    console.error('Matchup query error:', error);
    return {
      type: 'matchup',
      message: 'Unable to fetch matchup data right now. Try again shortly.',
    };
  }
}

function detectLeague(query: string): string {
  const queryLower = query.toLowerCase();
  
  if (queryLower.includes('nba') || queryLower.includes('basketball')) return 'NBA';
  if (queryLower.includes('nfl') || queryLower.includes('football')) return 'NFL';
  if (queryLower.includes('mlb') || queryLower.includes('baseball')) return 'MLB';
  if (queryLower.includes('nhl') || queryLower.includes('hockey')) return 'NHL';
  if (queryLower.includes('ufc') || queryLower.includes('mma')) return 'UFC';
  if (queryLower.includes('ncaa') || queryLower.includes('college')) return 'NCAAB';
  if (queryLower.includes('soccer') || queryLower.includes('epl')) return 'EPL';
  
  return 'NBA'; // Default
}

function getLeagueEmoji(league: string): string {
  const emojis: Record<string, string> = {
    NBA: '🏀',
    NFL: '🏈',
    MLB: '⚾',
    NHL: '🏒',
    UFC: '🥊',
    NCAAB: '🏀',
    EPL: '⚽',
  };
  return emojis[league] || '🎯';
}

function formatGameTime(isoTime: string): string {
  if (!isoTime) return 'TBD';
  
  try {
    const date = new Date(isoTime);
    return date.toLocaleString('en-US', {
      weekday: 'short',
      hour: 'numeric',
      minute: '2-digit',
      timeZone: 'America/New_York',
    }) + ' ET';
  } catch {
    return 'TBD';
  }
}
