import type express from 'express';
import type { Plugin, PluginContext } from '../../core/plugin.js';
import { sseBroadcast } from '../../core/sse.js';
import { getState, setState } from '../../core/persistence.js';
import { getProfile, getMatches, getMatchDetail, renewSummoner, REGIONS } from './opgg-api.js';
import type { RecentSearch } from './types.js';

// ── Recent searches ──

function getRecent(): RecentSearch[] {
  return getState<RecentSearch[]>('lolstats_recent', []);
}

function addRecent(entry: Omit<RecentSearch, 'timestamp'>): void {
  let list = getRecent();
  // Remove duplicate
  list = list.filter(
    r => !(r.game_name.toLowerCase() === entry.game_name.toLowerCase()
        && r.tag_line.toLowerCase() === entry.tag_line.toLowerCase()
        && r.region === entry.region),
  );
  // Add to front, cap at 10
  list.unshift({ ...entry, timestamp: Date.now() });
  if (list.length > 10) list.length = 10;
  setState('lolstats_recent', list);
  sseBroadcast({ type: 'lolstats_recent', plugin: 'lolstats', recentSearches: list });
}

// ── Plugin ──

const lolstatsPlugin: Plugin = {
  name: 'lolstats',
  version: '1.0.0',
  description: 'League of Legends Stats',

  async init(_ctx) {
    console.log('[LoLStats] Initialized — using op.gg MCP (no API key needed)');
  },

  registerRoutes(app: express.Application, _ctx: PluginContext) {
    // ── Regions ──
    app.get('/api/lolstats/regions', (_req, res) => {
      res.json(REGIONS);
    });

    // ── Summoner Profile Lookup ──
    app.get('/api/lolstats/profile', async (req, res) => {
      const { gameName, tagLine, region } = req.query as Record<string, string>;
      if (!gameName || !tagLine || !region) {
        return res.status(400).json({ error: 'gameName, tagLine, region required' });
      }
      try {
        const profile = await getProfile(gameName, tagLine, region);

        // Save to recent searches
        const soloRank = profile.league_stats?.find(l => l.game_type === 'SOLORANKED');
        addRecent({
          game_name: profile.game_name,
          tag_line: profile.tagline,
          region,
          profile_image_url: profile.profile_image_url,
          level: profile.level,
          tier: soloRank?.tier_info?.tier ?? undefined,
          rank: soloRank?.tier_info?.division != null
            ? String(soloRank.tier_info.division)
            : undefined,
        });

        res.json(profile);
      } catch (e: any) {
        console.error('[LoLStats] Profile error:', e.message);
        const status = e.message.includes('not found') ? 404 : 502;
        res.status(status).json({ error: e.message });
      }
    });

    // ── Match History ──
    app.get('/api/lolstats/matches', async (req, res) => {
      const { gameName, tagLine, region, limit } = req.query as Record<string, string>;
      if (!gameName || !tagLine || !region) {
        return res.status(400).json({ error: 'gameName, tagLine, region required' });
      }
      try {
        const matches = await getMatches(gameName, tagLine, region, Number(limit) || 10);
        res.json(matches);
      } catch (e: any) {
        console.error('[LoLStats] Matches error:', e.message);
        res.status(502).json({ error: e.message });
      }
    });

    // ── Match Detail ──
    app.get('/api/lolstats/match/:gameId', async (req, res) => {
      const { region, createdAt } = req.query as Record<string, string>;
      const { gameId } = req.params;
      if (!gameId || !region || !createdAt) {
        return res.status(400).json({ error: 'gameId, region, createdAt required' });
      }
      try {
        const match = await getMatchDetail(gameId, createdAt, region);
        res.json(match);
      } catch (e: any) {
        console.error('[LoLStats] Match detail error:', e.message);
        res.status(502).json({ error: e.message });
      }
    });

    // ── Summoner Renewal (refresh op.gg data) ──
    app.post('/api/lolstats/renew', async (req, res) => {
      const { gameName, tagLine, region } = req.query as Record<string, string>;
      if (!gameName || !tagLine || !region) {
        return res.status(400).json({ error: 'gameName, tagLine, region required' });
      }
      try {
        const result = await renewSummoner(gameName, tagLine, region);
        res.json(result);
      } catch (e: any) {
        console.error('[LoLStats] Renewal error:', e.message);
        res.status(502).json({ error: e.message });
      }
    });

    // ── Recent Searches ──
    app.get('/api/lolstats/recent', (_req, res) => {
      res.json(getRecent());
    });

    app.delete('/api/lolstats/recent', (_req, res) => {
      setState('lolstats_recent', []);
      sseBroadcast({ type: 'lolstats_recent', plugin: 'lolstats', recentSearches: [] });
      res.json({ ok: true });
    });
  },

  getSnapshot(_ctx) {
    return {
      lolstats: {
        recentSearches: getRecent(),
        regions: REGIONS,
      },
    };
  },

  async destroy() {
    console.log('[LoLStats] Destroyed');
  },
};

export default lolstatsPlugin;
