const express = require('express');
const { db } = require('../db/database');
const { authenticate } = require('../middleware/auth');

const router = express.Router();
router.use(authenticate);

// Country code lookup from coordinates (bounding box approach)
// Covers most countries — not pixel-perfect but good enough for visited-country tracking
const COUNTRY_BOXES = {
  AF:[60.5,29.4,75,38.5],AL:[19,39.6,21.1,42.7],DZ:[-8.7,19,12,37.1],AD:[1.4,42.4,1.8,42.7],AO:[11.7,-18.1,24.1,-4.4],
  AR:[-73.6,-55.1,-53.6,-21.8],AM:[43.4,38.8,46.6,41.3],AU:[112.9,-43.6,153.6,-10.7],AT:[9.5,46.4,17.2,49],AZ:[44.8,38.4,50.4,41.9],
  BR:[-73.9,-33.8,-34.8,5.3],BE:[2.5,49.5,6.4,51.5],BG:[22.4,41.2,28.6,44.2],CA:[-141,41.7,-52.6,83.1],CL:[-75.6,-55.9,-66.9,-17.5],
  CN:[73.6,18.2,134.8,53.6],CO:[-79.1,-4.3,-66.9,12.5],HR:[13.5,42.4,19.5,46.6],CZ:[12.1,48.6,18.9,51.1],DK:[8,54.6,15.2,57.8],
  EG:[24.7,22,37,31.7],EE:[21.8,57.5,28.2,59.7],FI:[20.6,59.8,31.6,70.1],FR:[-5.1,41.3,9.6,51.1],DE:[5.9,47.3,15.1,55.1],
  GR:[19.4,34.8,29.7,41.8],HU:[16,45.7,22.9,48.6],IS:[-24.5,63.4,-13.5,66.6],IN:[68.2,6.7,97.4,35.5],ID:[95.3,-11,141,5.9],
  IR:[44.1,25.1,63.3,39.8],IQ:[38.8,29.1,48.6,37.4],IE:[-10.5,51.4,-6,55.4],IL:[34.3,29.5,35.9,33.3],IT:[6.6,36.6,18.5,47.1],
  JP:[129.4,31.1,145.5,45.5],KE:[33.9,-4.7,41.9,5.5],KR:[126,33.2,129.6,38.6],LV:[21,55.7,28.2,58.1],LT:[21,53.9,26.8,56.5],
  LU:[5.7,49.4,6.5,50.2],MY:[99.6,0.9,119.3,7.4],MX:[-118.4,14.5,-86.7,32.7],MA:[-13.2,27.7,-1,35.9],NL:[3.4,50.8,7.2,53.5],
  NZ:[166.4,-47.3,178.5,-34.4],NO:[4.6,58,31.1,71.2],PK:[60.9,23.7,77.1,37.1],PE:[-81.3,-18.4,-68.7,-0.1],PH:[117,5,126.6,18.5],
  PL:[14.1,49,24.1,54.9],PT:[-9.5,36.8,-6.2,42.2],RO:[20.2,43.6,29.7,48.3],RU:[19.6,41.2,180,81.9],SA:[34.6,16.4,55.7,32.2],
  RS:[18.8,42.2,23,46.2],SK:[16.8,47.7,22.6,49.6],SI:[13.4,45.4,16.6,46.9],ZA:[16.5,-34.8,32.9,-22.1],ES:[-9.4,36,-0.2,43.8],
  SE:[11.1,55.3,24.2,69.1],CH:[6,45.8,10.5,47.8],TH:[97.3,5.6,105.6,20.5],TR:[26,36,44.8,42.1],UA:[22.1,44.4,40.2,52.4],
  AE:[51.6,22.6,56.4,26.1],GB:[-8,49.9,2,60.9],US:[-125,24.5,-66.9,49.4],VN:[102.1,8.6,109.5,23.4],
};

function getCountryFromCoords(lat, lng) {
  for (const [code, [minLng, minLat, maxLng, maxLat]] of Object.entries(COUNTRY_BOXES)) {
    if (lat >= minLat && lat <= maxLat && lng >= minLng && lng <= maxLng) {
      return code;
    }
  }
  return null;
}

function getCountryFromAddress(address) {
  if (!address) return null;
  // Take last segment after comma, trim
  const parts = address.split(',').map(s => s.trim()).filter(Boolean);
  if (parts.length === 0) return null;
  const last = parts[parts.length - 1];
  // Try to match known country names to codes
  const NAME_TO_CODE = {
    'germany':'DE','deutschland':'DE','france':'FR','frankreich':'FR','spain':'ES','spanien':'ES',
    'italy':'IT','italien':'IT','united kingdom':'GB','uk':'GB','england':'GB','united states':'US',
    'usa':'US','netherlands':'NL','niederlande':'NL','austria':'AT','österreich':'AT','switzerland':'CH',
    'schweiz':'CH','portugal':'PT','greece':'GR','griechenland':'GR','turkey':'TR','türkei':'TR',
    'croatia':'HR','kroatien':'HR','czech republic':'CZ','tschechien':'CZ','czechia':'CZ',
    'poland':'PL','polen':'PL','sweden':'SE','schweden':'SE','norway':'NO','norwegen':'NO',
    'denmark':'DK','dänemark':'DK','finland':'FI','finnland':'FI','belgium':'BE','belgien':'BE',
    'ireland':'IE','irland':'IE','hungary':'HU','ungarn':'HU','romania':'RO','rumänien':'RO',
    'bulgaria':'BG','bulgarien':'BG','japan':'JP','china':'CN','australia':'AU','australien':'AU',
    'canada':'CA','kanada':'CA','mexico':'MX','mexiko':'MX','brazil':'BR','brasilien':'BR',
    'argentina':'AR','argentinien':'AR','thailand':'TH','indonesia':'ID','indonesien':'ID',
    'india':'IN','indien':'IN','egypt':'EG','ägypten':'EG','morocco':'MA','marokko':'MA',
    'south africa':'ZA','südafrika':'ZA','new zealand':'NZ','neuseeland':'NZ','iceland':'IS','island':'IS',
    'luxembourg':'LU','luxemburg':'LU','slovenia':'SI','slowenien':'SI','slovakia':'SK','slowakei':'SK',
    'estonia':'EE','estland':'EE','latvia':'LV','lettland':'LV','lithuania':'LT','litauen':'LT',
    'serbia':'RS','serbien':'RS','israel':'IL','russia':'RU','russland':'RU','ukraine':'UA',
    'vietnam':'VN','south korea':'KR','südkorea':'KR','philippines':'PH','philippinen':'PH',
    'malaysia':'MY','colombia':'CO','kolumbien':'CO','peru':'PE','chile':'CL','iran':'IR',
    'iraq':'IQ','irak':'IQ','pakistan':'PK','kenya':'KE','kenia':'KE','nigeria':'NG',
    'saudi arabia':'SA','saudi-arabien':'SA','albania':'AL','albanien':'AL',
    '日本':'JP','中国':'CN','한국':'KR','대한민국':'KR','ไทย':'TH',
  };
  const normalized = last.toLowerCase();
  if (NAME_TO_CODE[normalized]) return NAME_TO_CODE[normalized];
  // Try original case (for non-Latin scripts like 日本)
  if (NAME_TO_CODE[last]) return NAME_TO_CODE[last];
  // Try 2-letter code directly
  if (last.length === 2 && last === last.toUpperCase()) return last;
  return null;
}

// GET /api/addons/atlas/stats
router.get('/stats', (req, res) => {
  const userId = req.user.id;

  // Get all trips (own + shared)
  const trips = db.prepare(`
    SELECT DISTINCT t.* FROM trips t
    LEFT JOIN trip_members m ON m.trip_id = t.id AND m.user_id = ?
    WHERE t.user_id = ? OR m.user_id = ?
    ORDER BY t.start_date DESC
  `).all(userId, userId, userId);

  // Get all places from those trips
  const tripIds = trips.map(t => t.id);
  if (tripIds.length === 0) {
    return res.json({ countries: [], trips: [], stats: { totalTrips: 0, totalPlaces: 0, totalCountries: 0, totalDays: 0 } });
  }

  const placeholders = tripIds.map(() => '?').join(',');
  const places = db.prepare(`SELECT * FROM places WHERE trip_id IN (${placeholders})`).all(...tripIds);

  // Extract countries
  const countrySet = new Map(); // code -> { code, places: [], trips: Set }
  for (const place of places) {
    let code = getCountryFromAddress(place.address);
    if (!code && place.lat && place.lng) {
      code = getCountryFromCoords(place.lat, place.lng);
    }
    if (code) {
      if (!countrySet.has(code)) {
        countrySet.set(code, { code, places: [], tripIds: new Set() });
      }
      countrySet.get(code).places.push({ id: place.id, name: place.name, lat: place.lat, lng: place.lng });
      countrySet.get(code).tripIds.add(place.trip_id);
    }
  }

  // Calculate total days across all trips
  let totalDays = 0;
  for (const trip of trips) {
    if (trip.start_date && trip.end_date) {
      const start = new Date(trip.start_date);
      const end = new Date(trip.end_date);
      const diff = Math.ceil((end - start) / (1000 * 60 * 60 * 24)) + 1;
      if (diff > 0) totalDays += diff;
    }
  }

  const countries = [...countrySet.values()].map(c => {
    const countryTrips = trips.filter(t => c.tripIds.has(t.id));
    const dates = countryTrips.map(t => t.start_date).filter(Boolean).sort();
    return {
      code: c.code,
      placeCount: c.places.length,
      tripCount: c.tripIds.size,
      firstVisit: dates[0] || null,
      lastVisit: dates[dates.length - 1] || null,
    };
  });

  // Unique cities (extract city from address — second to last comma segment)
  // Strip postal codes and normalize to avoid duplicates like "Tokyo" vs "Tokyo 131-0045"
  const citySet = new Set();
  for (const place of places) {
    if (place.address) {
      const parts = place.address.split(',').map(s => s.trim()).filter(Boolean);
      let raw = parts.length >= 2 ? parts[parts.length - 2] : parts[0];
      if (raw) {
        const city = raw.replace(/[\d\-−〒]+/g, '').trim().toLowerCase();
        if (city) citySet.add(city);
      }
    }
  }
  const totalCities = citySet.size;

  // Most visited country
  const mostVisited = countries.length > 0 ? countries.reduce((a, b) => a.placeCount > b.placeCount ? a : b) : null;

  // Continent breakdown
  const CONTINENT_MAP = {
    AF:'Africa',AL:'Europe',DZ:'Africa',AD:'Europe',AO:'Africa',AR:'South America',AM:'Asia',AU:'Oceania',AT:'Europe',AZ:'Asia',
    BR:'South America',BE:'Europe',BG:'Europe',CA:'North America',CL:'South America',CN:'Asia',CO:'South America',HR:'Europe',CZ:'Europe',DK:'Europe',
    EG:'Africa',EE:'Europe',FI:'Europe',FR:'Europe',DE:'Europe',GR:'Europe',HU:'Europe',IS:'Europe',IN:'Asia',ID:'Asia',
    IR:'Asia',IQ:'Asia',IE:'Europe',IL:'Asia',IT:'Europe',JP:'Asia',KE:'Africa',KR:'Asia',LV:'Europe',LT:'Europe',
    LU:'Europe',MY:'Asia',MX:'North America',MA:'Africa',NL:'Europe',NZ:'Oceania',NO:'Europe',PK:'Asia',PE:'South America',PH:'Asia',
    PL:'Europe',PT:'Europe',RO:'Europe',RU:'Europe',SA:'Asia',RS:'Europe',SK:'Europe',SI:'Europe',ZA:'Africa',ES:'Europe',
    SE:'Europe',CH:'Europe',TH:'Asia',TR:'Europe',UA:'Europe',AE:'Asia',GB:'Europe',US:'North America',VN:'Asia',NG:'Africa',
  };
  const continents = {};
  countries.forEach(c => {
    const cont = CONTINENT_MAP[c.code] || 'Other';
    continents[cont] = (continents[cont] || 0) + 1;
  });

  // Last trip (most recent past trip)
  const now = new Date().toISOString().split('T')[0];
  const pastTrips = trips.filter(t => t.end_date && t.end_date <= now).sort((a, b) => b.end_date.localeCompare(a.end_date));
  const lastTrip = pastTrips[0] ? { id: pastTrips[0].id, title: pastTrips[0].title, start_date: pastTrips[0].start_date, end_date: pastTrips[0].end_date } : null;
  // Find country for last trip
  if (lastTrip) {
    const lastTripPlaces = places.filter(p => p.trip_id === lastTrip.id);
    for (const p of lastTripPlaces) {
      let code = getCountryFromAddress(p.address);
      if (!code && p.lat && p.lng) code = getCountryFromCoords(p.lat, p.lng);
      if (code) { lastTrip.countryCode = code; break; }
    }
  }

  // Next trip (earliest future trip)
  const futureTrips = trips.filter(t => t.start_date && t.start_date > now).sort((a, b) => a.start_date.localeCompare(b.start_date));
  const nextTrip = futureTrips[0] ? { id: futureTrips[0].id, title: futureTrips[0].title, start_date: futureTrips[0].start_date } : null;
  if (nextTrip) {
    const diff = Math.ceil((new Date(nextTrip.start_date) - new Date()) / (1000 * 60 * 60 * 24));
    nextTrip.daysUntil = Math.max(0, diff);
  }

  // Travel streak (consecutive years with at least one trip)
  const tripYears = new Set(trips.filter(t => t.start_date).map(t => parseInt(t.start_date.split('-')[0])));
  let streak = 0;
  const currentYear = new Date().getFullYear();
  for (let y = currentYear; y >= 2000; y--) {
    if (tripYears.has(y)) streak++;
    else break;
  }
  const firstYear = tripYears.size > 0 ? Math.min(...tripYears) : null;

  res.json({
    countries,
    stats: {
      totalTrips: trips.length,
      totalPlaces: places.length,
      totalCountries: countries.length,
      totalDays,
      totalCities,
    },
    mostVisited,
    continents,
    lastTrip,
    nextTrip,
    streak,
    firstYear,
    tripsThisYear: trips.filter(t => t.start_date && t.start_date.startsWith(String(currentYear))).length,
  });
});

// GET /api/addons/atlas/country/:code — details for a country
router.get('/country/:code', (req, res) => {
  const userId = req.user.id;
  const code = req.params.code.toUpperCase();

  const trips = db.prepare(`
    SELECT DISTINCT t.* FROM trips t
    LEFT JOIN trip_members m ON m.trip_id = t.id AND m.user_id = ?
    WHERE t.user_id = ? OR m.user_id = ?
  `).all(userId, userId, userId);

  const tripIds = trips.map(t => t.id);
  if (tripIds.length === 0) return res.json({ places: [], trips: [] });

  const placeholders = tripIds.map(() => '?').join(',');
  const places = db.prepare(`SELECT * FROM places WHERE trip_id IN (${placeholders})`).all(...tripIds);

  const matchingPlaces = [];
  const matchingTripIds = new Set();

  for (const place of places) {
    let pCode = getCountryFromAddress(place.address);
    if (!pCode && place.lat && place.lng) pCode = getCountryFromCoords(place.lat, place.lng);
    if (pCode === code) {
      matchingPlaces.push({ id: place.id, name: place.name, address: place.address, lat: place.lat, lng: place.lng, trip_id: place.trip_id });
      matchingTripIds.add(place.trip_id);
    }
  }

  const matchingTrips = trips.filter(t => matchingTripIds.has(t.id)).map(t => ({ id: t.id, title: t.title, start_date: t.start_date, end_date: t.end_date }));

  res.json({ places: matchingPlaces, trips: matchingTrips });
});

module.exports = router;
