// Client-side analytics tracking system
// Tracks visitors, IP addresses, countries, page views, devices

export interface VisitorRecord {
  id: string;
  ip: string;
  country: string;
  countryCode: string;
  city: string;
  page: string;
  timestamp: number;
  date: string;
  device: string;
  browser: string;
  os: string;
  referrer: string;
  sessionId: string;
  isNewVisitor: boolean;
}

export interface DailyStats {
  date: string;
  totalVisits: number;
  uniqueVisitors: number;
  pageViews: Record<string, number>;
  countries: Record<string, number>;
  devices: Record<string, number>;
  browsers: Record<string, number>;
}

const STORAGE_KEY = 'mfa-analytics';
const SESSION_ID_KEY = 'mfa-session-id';
const IP_FETCHED_KEY = 'mfa-ip-fetched';

function generateId(): string {
  return Date.now().toString(36) + Math.random().toString(36).substr(2, 5);
}

function getSessionId(): string {
  let sid = sessionStorage.getItem(SESSION_ID_KEY);
  if (!sid) {
    sid = generateId();
    sessionStorage.setItem(SESSION_ID_KEY, sid);
  }
  return sid;
}

function getDeviceType(): string {
  const w = window.innerWidth;
  if (w < 768) return 'Mobile';
  if (w < 1024) return 'Tablet';
  return 'Desktop';
}

function getBrowser(): string {
  const ua = navigator.userAgent;
  if (ua.includes('Chrome')) return 'Chrome';
  if (ua.includes('Firefox')) return 'Firefox';
  if (ua.includes('Safari')) return 'Safari';
  if (ua.includes('Edge')) return 'Edge';
  return 'Other';
}

function getOS(): string {
  const ua = navigator.userAgent;
  if (ua.includes('Windows')) return 'Windows';
  if (ua.includes('Mac')) return 'MacOS';
  if (ua.includes('Linux')) return 'Linux';
  if (ua.includes('Android')) return 'Android';
  if (ua.includes('iPhone') || ua.includes('iPad')) return 'iOS';
  return 'Other';
}

function getToday(): string {
  return new Date().toISOString().split('T')[0];
}

function loadRecords(): VisitorRecord[] {
  try {
    const raw = localStorage.getItem(STORAGE_KEY);
    return raw ? JSON.parse(raw) : [];
  } catch { return []; }
}

function saveRecords(records: VisitorRecord[]) {
  localStorage.setItem(STORAGE_KEY, JSON.stringify(records));
}

// Check if this IP already visited today
function checkIsNewVisitor(ip: string): boolean {
  const records = loadRecords();
  const today = getToday();
  return !records.some(r => r.ip === ip && r.date === today);
}

// Main tracking function - call this on every page visit
export async function trackVisit(page: string = window.location.pathname): Promise<VisitorRecord | null> {
  // Don't track admin pages
  if (page.includes('admin')) return null;

  const alreadyFetched = sessionStorage.getItem(IP_FETCHED_KEY);
  if (alreadyFetched) {
    // Just track the page view without fetching IP again
    const records = loadRecords();
    const sessionId = getSessionId();
    const lastRecord = records.filter(r => r.sessionId === sessionId).pop();
    if (lastRecord) {
      const newRecord: VisitorRecord = {
        ...lastRecord,
        id: generateId(),
        page,
        timestamp: Date.now(),
        date: getToday(),
        isNewVisitor: false,
      };
      records.push(newRecord);
      // Keep max 5000 records to avoid storage issues
      if (records.length > 5000) {
        records.splice(0, records.length - 5000);
      }
      saveRecords(records);
      return newRecord;
    }
    return null;
  }

  // First visit in this session - fetch IP and geolocation
  sessionStorage.setItem(IP_FETCHED_KEY, 'true');

  let ip = 'Unknown';
  let country = 'Unknown';
  let countryCode = '';
  let city = '';

  try {
    // Use ipapi.co for free IP geolocation (no API key needed, 45 requests/min free)
    const res = await fetch('https://ipapi.co/json/', {
      method: 'GET',
      // Use a timeout
      signal: AbortSignal.timeout(5000)
    });
    if (res.ok) {
      const data = await res.json();
      ip = data.ip || 'Unknown';
      country = data.country_name || 'Unknown';
      countryCode = data.country_code || '';
      city = data.city || '';
    }
  } catch {
    // Fallback: try ipify for just IP
    try {
      const res2 = await fetch('https://api.ipify.org?format=json', { signal: AbortSignal.timeout(3000) });
      if (res2.ok) {
        const data2 = await res2.json();
        ip = data2.ip || 'Unknown';
      }
    } catch {
      // Silent fail - still track without IP
    }
  }

  const isNew = checkIsNewVisitor(ip);
  const record: VisitorRecord = {
    id: generateId(),
    ip,
    country,
    countryCode,
    city,
    page,
    timestamp: Date.now(),
    date: getToday(),
    device: getDeviceType(),
    browser: getBrowser(),
    os: getOS(),
    referrer: document.referrer || 'Direct',
    sessionId: getSessionId(),
    isNewVisitor: isNew,
  };

  const records = loadRecords();
  records.push(record);
  // Keep max 5000 records
  if (records.length > 5000) {
    records.splice(0, records.length - 5000);
  }
  saveRecords(records);

  return record;
}

// Get all analytics data
export function getAllRecords(): VisitorRecord[] {
  return loadRecords();
}

// Get records for a specific date
export function getRecordsByDate(date: string): VisitorRecord[] {
  return loadRecords().filter(r => r.date === date);
}

// Get records for date range
export function getRecordsByRange(startDate: string, endDate: string): VisitorRecord[] {
  return loadRecords().filter(r => r.date >= startDate && r.date <= endDate);
}

// Get today's stats
export function getTodayStats(): { visits: number; uniqueVisitors: number; pageViews: Record<string, number>; countries: Record<string, number> } {
  const today = getToday();
  const records = loadRecords().filter(r => r.date === today);
  const pageViews: Record<string, number> = {};
  const countries: Record<string, number> = {};

  records.forEach(r => {
    pageViews[r.page] = (pageViews[r.page] || 0) + 1;
    if (r.country !== 'Unknown') {
      countries[r.country] = (countries[r.country] || 0) + 1;
    }
  });

  return {
    visits: records.length,
    uniqueVisitors: new Set(records.filter(r => r.isNewVisitor).map(r => r.ip)).size || records.length,
    pageViews,
    countries,
  };
}

// Get daily stats for the last N days
export function getDailyStats(days: number = 30): DailyStats[] {
  const records = loadRecords();
  const stats: Record<string, DailyStats> = {};

  records.forEach(r => {
    if (!stats[r.date]) {
      stats[r.date] = {
        date: r.date,
        totalVisits: 0,
        uniqueVisitors: 0,
        pageViews: {},
        countries: {},
        devices: {},
        browsers: {},
      };
    }
    stats[r.date].totalVisits++;
    stats[r.date].pageViews[r.page] = (stats[r.date].pageViews[r.page] || 0) + 1;
    if (r.country !== 'Unknown') {
      stats[r.date].countries[r.country] = (stats[r.date].countries[r.country] || 0) + 1;
    }
    stats[r.date].devices[r.device] = (stats[r.date].devices[r.device] || 0) + 1;
    stats[r.date].browsers[r.browser] = (stats[r.date].browsers[r.browser] || 0) + 1;
  });

  // Calculate unique visitors per day
  Object.keys(stats).forEach(date => {
    const dayRecords = records.filter(r => r.date === date);
    stats[date].uniqueVisitors = new Set(dayRecords.map(r => r.ip)).size;
  });

  return Object.values(stats).sort((a, b) => b.date.localeCompare(a.date)).slice(0, days);
}

// Get top pages
export function getTopPages(limit: number = 10): { page: string; views: number }[] {
  const records = loadRecords();
  const pages: Record<string, number> = {};
  records.forEach(r => { pages[r.page] = (pages[r.page] || 0) + 1; });
  return Object.entries(pages)
    .map(([page, views]) => ({ page, views }))
    .sort((a, b) => b.views - a.views)
    .slice(0, limit);
}

// Get top countries
export function getTopCountries(limit: number = 15): { country: string; code: string; visitors: number }[] {
  const records = loadRecords().filter(r => r.country !== 'Unknown');
  const countries: Record<string, { count: number; code: string }> = {};
  records.forEach(r => {
    if (!countries[r.country]) countries[r.country] = { count: 0, code: r.countryCode };
    countries[r.country].count++;
  });
  return Object.entries(countries)
    .map(([country, data]) => ({ country, code: data.code, visitors: data.count }))
    .sort((a, b) => b.visitors - a.visitors)
    .slice(0, limit);
}

// Get recent visitors
export function getRecentVisitors(limit: number = 50): VisitorRecord[] {
  return loadRecords().sort((a, b) => b.timestamp - a.timestamp).slice(0, limit);
}

// Get device breakdown
export function getDeviceBreakdown(): { device: string; count: number }[] {
  const records = loadRecords();
  const devices: Record<string, number> = {};
  records.forEach(r => { devices[r.device] = (devices[r.device] || 0) + 1; });
  return Object.entries(devices).map(([device, count]) => ({ device, count })).sort((a, b) => b.count - a.count);
}

// Get browser breakdown
export function getBrowserBreakdown(): { browser: string; count: number }[] {
  const records = loadRecords();
  const browsers: Record<string, number> = {};
  records.forEach(r => { browsers[r.browser] = (browsers[r.browser] || 0) + 1; });
  return Object.entries(browsers).map(([browser, count]) => ({ browser, count })).sort((a, b) => b.count - a.count);
}

// Get total stats
export function getTotalStats(): { totalVisits: number; totalVisitors: number; totalCountries: number; todayVisits: number; todayUnique: number } {
  const records = loadRecords();
  const today = getTodayStats();
  return {
    totalVisits: records.length,
    totalVisitors: new Set(records.map(r => r.ip)).size,
    totalCountries: new Set(records.filter(r => r.country !== 'Unknown').map(r => r.country)).size,
    todayVisits: today.visits,
    todayUnique: today.uniqueVisitors,
  };
}

// Clear all analytics data
export function clearAnalytics() {
  localStorage.removeItem(STORAGE_KEY);
  sessionStorage.removeItem(IP_FETCHED_KEY);
  sessionStorage.removeItem(SESSION_ID_KEY);
}

// Seed demo data (for first-time admin view)
export function seedDemoData() {
  const existing = loadRecords();
  if (existing.length > 0) return; // Don't seed if real data exists

  const demoRecords: VisitorRecord[] = [];
  const pages = ['/', '/shop', '/blog', '/product/kanva-pro', '/product/chatgpt-plus', '/faq', '/contact', '/free-tools', '/our-story', '/trust'];
  const countries = [
    { name: 'India', code: 'IN' }, { name: 'United States', code: 'US' }, { name: 'United Kingdom', code: 'GB' },
    { name: 'Pakistan', code: 'PK' }, { name: 'Bangladesh', code: 'BD' }, { name: 'Canada', code: 'CA' },
    { name: 'Australia', code: 'AU' }, { name: 'Germany', code: 'DE' }, { name: 'France', code: 'FR' },
    { name: 'UAE', code: 'AE' }, { name: 'Singapore', code: 'SG' }, { name: 'Malaysia', code: 'MY' },
    { name: 'Nepal', code: 'NP' }, { name: 'Sri Lanka', code: 'LK' }, { name: 'Nigeria', code: 'NG' },
  ];
  const devices = ['Desktop', 'Mobile', 'Tablet'];
  const browsers = ['Chrome', 'Firefox', 'Safari', 'Edge'];
  const cities = ['Mumbai', 'Delhi', 'Bangalore', 'Hyderabad', 'Chennai', 'New York', 'London', 'Dubai', 'Karachi', 'Dhaka'];

  // Generate 30 days of demo data
  for (let day = 0; day < 30; day++) {
    const date = new Date();
    date.setDate(date.getDate() - day);
    const dateStr = date.toISOString().split('T')[0];
    const visitsForDay = Math.floor(Math.random() * 40) + 10; // 10-50 visits per day

    for (let v = 0; v < visitsForDay; v++) {
      const country = countries[Math.floor(Math.random() * countries.length)];
      const ip = `${Math.floor(Math.random() * 255)}.${Math.floor(Math.random() * 255)}.${Math.floor(Math.random() * 255)}.${Math.floor(Math.random() * 255)}`;

      demoRecords.push({
        id: generateId() + day + v,
        ip,
        country: country.name,
        countryCode: country.code,
        city: cities[Math.floor(Math.random() * cities.length)],
        page: pages[Math.floor(Math.random() * pages.length)],
        timestamp: date.getTime() + Math.floor(Math.random() * 86400000),
        date: dateStr,
        device: devices[Math.floor(Math.random() * devices.length)],
        browser: browsers[Math.floor(Math.random() * browsers.length)],
        os: ['Windows', 'MacOS', 'Android', 'iOS'][Math.floor(Math.random() * 4)],
        referrer: Math.random() > 0.5 ? 'https://google.com' : (Math.random() > 0.5 ? 'https://instagram.com' : 'Direct'),
        sessionId: generateId() + Math.floor(v / 3),
        isNewVisitor: v % 3 === 0,
      });
    }
  }

  saveRecords(demoRecords);
}
