const express = require('express');
const router = express.Router();
const { pool } = require('../db');
const { authenticateToken } = require('../middleware/auth');

router.get('/status', async (req, res) => {
  try {
    const result = await pool.query(
      'SELECT * FROM crawls ORDER BY crawled_at DESC LIMIT 10'
    );
    res.json(result.rows);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

router.get('/all', async (req, res) => {
  try {
    const result = await pool.query(`
      WITH latest_crawls AS (
        SELECT DISTINCT ON (site_name) id, url, site_name, crawled_at, status
        FROM crawls
        ORDER BY site_name, crawled_at DESC
      )
      SELECT c.id as crawl_id, c.url, c.site_name, c.crawled_at, c.status,
             json_agg(
               json_build_object(
                 'position', ca.position,
                 'casino_name', ca.casino_name,
                 'url', ca.url,
                 'bonus_offer', ca.bonus_offer,
                 'favicon_url', ca.favicon_url
               ) ORDER BY ca.position
             ) as casinos
      FROM latest_crawls c
      LEFT JOIN casinos ca ON ca.crawl_id = c.id
      GROUP BY c.id, c.url, c.site_name, c.crawled_at, c.status
      ORDER BY c.crawled_at DESC
    `);
    res.json(result.rows);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

router.get('/position-history', async (req, res) => {
  try {
    const { casino_name, site_name } = req.query;

    if (!casino_name || !site_name) {
      return res.status(400).json({ error: 'casino_name and site_name are required' });
    }

    // Grab all raw crawl results for this casino+site pair, first within each crawl
    const result = await pool.query(`
      WITH ranked AS (
        SELECT c.crawled_at, ca.position,
               ROW_NUMBER() OVER (ORDER BY c.crawled_at ASC) AS rn
        FROM crawls c
        JOIN casinos ca ON ca.crawl_id = c.id
        WHERE ca.casino_name = $1 AND c.site_name = $2
        ORDER BY c.crawled_at ASC
      )
      SELECT crawled_at, position FROM ranked ORDER BY crawled_at ASC
    `, [casino_name, site_name]);

    const all = result.rows;

    const points = all.map(p => ({
      label: new Date(p.crawled_at).toLocaleString(undefined, { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' }),
      position: Number(p.position)
    }));

    res.json(points);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

router.get('/casino-report', async (req, res) => {
  try {
    const result = await pool.query(`
      WITH latest_crawls AS (
        SELECT DISTINCT ON (site_name) id, site_name, url, crawled_at
        FROM crawls
        ORDER BY site_name, crawled_at DESC
      ),
      casino_sites AS (
        SELECT c.casino_name, c.position, c.favicon_url, c.url AS casino_url,
               lc.id AS crawl_id, lc.site_name, lc.url AS site_url, lc.crawled_at,
               ROW_NUMBER() OVER (PARTITION BY c.casino_name, lc.site_name ORDER BY lc.crawled_at DESC) AS rn
        FROM casinos c
        JOIN latest_crawls lc ON lc.id = c.crawl_id
      ),
      unique_pairs AS (
        SELECT * FROM casino_sites WHERE rn = 1
      ),
      first_occurrence AS (
        SELECT casino_name, MIN(casino_url) AS casino_url, MIN(favicon_url) AS favicon_url
        FROM unique_pairs
        GROUP BY casino_name
      )
      SELECT
        fo.casino_name,
        fo.casino_url,
        fo.favicon_url,
        json_agg(
          json_build_object(
            'crawl_id', up.crawl_id,
            'site_name', up.site_name,
            'site_url', up.site_url,
            'position', up.position,
            'crawled_at', up.crawled_at
          ) ORDER BY up.position
        ) AS sites
      FROM unique_pairs up
      JOIN first_occurrence fo ON fo.casino_name = up.casino_name
      GROUP BY fo.casino_name, fo.casino_url, fo.favicon_url
      ORDER BY fo.casino_name
    `);
    res.json(result.rows);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

router.get('/:id', async (req, res) => {
  try {
    const crawl = await pool.query('SELECT * FROM crawls WHERE id = $1', [req.params.id]);
    
    if (crawl.rows.length === 0) {
      return res.status(404).json({ error: 'Crawl not found' });
    }

    const casinos = await pool.query(
      'SELECT * FROM casinos WHERE crawl_id = $1 ORDER BY position',
      [req.params.id]
    );

    res.json({
      ...crawl.rows[0],
      casinos: casinos.rows
    });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

router.post('/run', async (req, res) => {
  try {
    const CasinoCrawler = require('../services/crawler');
    const crawler = new CasinoCrawler();
    
    await crawler.initialize();
    
    const siteUrl = req.body.url || 'https://m.top10onlineslots.co.uk/onlineslots/';
    const siteName = req.body.siteName || 'Manual Crawl';

    const result = await crawler.crawl(siteUrl, siteName);
    await crawler.close();

    if (result) {
      res.json({ 
        success: true, 
        message: `Crawled ${result.count} casinos`,
        crawlId: result.crawlId 
      });
    } else {
      res.status(500).json({ error: 'Crawl failed' });
    }
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

router.post('/run-all', async (req, res) => {
  try {
    const CasinoCrawler = require('../services/crawler');
    const crawler = new CasinoCrawler();
    
    await crawler.initialize();

    const sites = [
      { url: 'https://m.top10onlineslots.co.uk/onlineslots/', name: 'Top10OnlineSlots' },
      { url: 'https://ubet.co.uk/casino/best-slots-chart', name: 'UBetting Best Slots' }
    ];

    const results = [];
    for (const site of sites) {
      const result = await crawler.crawl(site.url, site.name);
      results.push({ siteName: site.name, success: !!result });
      
      if (result) {
        await new Promise(resolve => setTimeout(resolve, 3000));
      }
    }

    await crawler.close();
    res.json({ success: true, results });
  } catch (error) {
    if (global?.crawlerInstance) {
      try { await global.crawlerInstance.close(); } catch(e) {}
    }
    res.status(500).json({ error: error.message });
  }
});

module.exports = router;
