"use client";

import { useState, useEffect } from 'react';
import { GeoData } from '@/app/api/types';
import { getLocationsFromIPs } from '@/app/utils/ipLocation';

interface GeoAnalyticsProps {
  data: GeoData[];
}

// Interface for IP location data in our cache
interface IpLocationDetail {
  country: string;
  city: string;
  region: string;
  continent: string;
}

// Cache for IP location data
interface LocationCache {
  [key: string]: IpLocationDetail;
}

export default function GeoAnalytics({ data }: GeoAnalyticsProps) {
  const [viewMode, setViewMode] = useState<'country' | 'city' | 'region' | 'continent'>('country');
  const [locationCache, setLocationCache] = useState<LocationCache>({});
  const [isLoading, setIsLoading] = useState(false);
  // Track IPs that failed to resolve
  const [failedIPs, setFailedIPs] = useState<Set<string>>(new Set());

  // 安全地格式化数字
  const formatNumber = (value: number | undefined | null): string => {
    if (value === undefined || value === null) return '0';
    return value.toLocaleString();
  };

  // 安全地格式化百分比
  const formatPercent = (value: number | undefined | null): string => {
    if (value === undefined || value === null) return '0';
    return value.toFixed(1);
  };

  const sortedData = [...data].sort((a, b) => (b.visits || 0) - (a.visits || 0));

  // Handle tab selection - only change local view mode
  const handleViewModeChange = (mode: 'country' | 'city' | 'region' | 'continent') => {
    setViewMode(mode);
  };

  // Load location data for all IPs when the data changes
  useEffect(() => {
    const fetchLocations = async () => {
      if (sortedData.length === 0) return;
      
      setIsLoading(true);
      const tempCache: LocationCache = {...locationCache};
      const tempFailedIPs = new Set(failedIPs);
      
      // Get all unique IPs that aren't already in the cache and haven't failed
      const uniqueIPs = [...new Set(sortedData.map(item => item.location))].filter(ip => 
        ip && 
        ip !== 'Unknown' && 
        !tempCache[ip] && 
        !tempFailedIPs.has(ip)
      );
      
      if (uniqueIPs.length === 0) {
        setIsLoading(false);
        return;
      }
      
      try {
        // Use batch lookup for better performance
        const batchResults = await getLocationsFromIPs(uniqueIPs);
        
        // Convert results to our cache format
        for (const [ip, data] of Object.entries(batchResults)) {
          if (data) {
            tempCache[ip] = {
              country: data.country_name,
              city: data.city,
              region: data.region,
              continent: data.continent_name
            };
          } else {
            // Mark as failed
            tempFailedIPs.add(ip);
          }
        }
        
        setLocationCache(tempCache);
        setFailedIPs(tempFailedIPs);
      } catch (error) {
        console.error('Error fetching location data:', error);
      } finally {
        setIsLoading(false);
      }
    };
    
    fetchLocations();
  }, [data]);

  // Get the appropriate location value based on the current view mode
  const getLocationValue = (item: GeoData): string => {
    const ip = item.location || '';
    
    // If there's no IP or it's "Unknown", return that value
    if (!ip || ip === 'Unknown') return 'Unknown';
    
    // If IP failed to resolve, return Unknown
    if (failedIPs.has(ip)) {
      return 'Unknown';
    }
    
    // Return from cache if available
    if (locationCache[ip]) {
      switch (viewMode) {
        case 'country':
          return locationCache[ip].country || 'Unknown';
        case 'city':
          return locationCache[ip].city || 'Unknown';
        case 'region':
          return locationCache[ip].region || 'Unknown';
        case 'continent':
          return locationCache[ip].continent || 'Unknown';
        default:
          return ip;
      }
    }
    
    // Return placeholder if not in cache yet
    return `Loading...`;
  };

  // Get the appropriate area value based on the current view mode
  const getAreaValue = (item: GeoData): string => {
    const ip = item.location || '';
    
    // If there's no IP or it's "Unknown", return empty string
    if (!ip || ip === 'Unknown' || failedIPs.has(ip)) return '';
    
    // Return from cache if available
    if (locationCache[ip]) {
      switch (viewMode) {
        case 'country':
          // For country view, show the continent as area
          return locationCache[ip].continent || '';
        case 'city':
          // For city view, show the country and region
          return `${locationCache[ip].country}, ${locationCache[ip].region}`;
        case 'region':
          // For region view, show the country
          return locationCache[ip].country || '';
        case 'continent':
          // For continent view, no additional area needed
          return '';
        default:
          return '';
      }
    }
    
    // Return empty if not in cache yet
    return '';
  };

  return (
    <div>
      {/* Tabs for geographic levels */}
      <div className="flex border-b mb-6">
        <button 
          onClick={() => handleViewModeChange('country')}
          className={`px-4 py-2 ${viewMode === 'country' ? 'border-b-2 border-blue-500 text-blue-600' : 'text-gray-500'}`}
        >
          Countries
        </button>
        <button 
          onClick={() => handleViewModeChange('city')}
          className={`px-4 py-2 ${viewMode === 'city' ? 'border-b-2 border-blue-500 text-blue-600' : 'text-gray-500'}`}
        >
          Cities
        </button>
        <button 
          onClick={() => handleViewModeChange('region')}
          className={`px-4 py-2 ${viewMode === 'region' ? 'border-b-2 border-blue-500 text-blue-600' : 'text-gray-500'}`}
        >
          Regions
        </button>
        <button 
          onClick={() => handleViewModeChange('continent')}
          className={`px-4 py-2 ${viewMode === 'continent' ? 'border-b-2 border-blue-500 text-blue-600' : 'text-gray-500'}`}
        >
          Continents
        </button>
      </div>

      {/* Loading indicator */}
      {isLoading && (
        <div className="flex justify-center items-center py-2 mb-4">
          <div className="animate-spin rounded-full h-4 w-4 border-b-2 border-blue-500 mr-2"></div>
          <span className="text-sm text-gray-500">Loading location data...</span>
        </div>
      )}

      {/* Table with added area column */}
      <div className="overflow-x-auto">
        <table className="min-w-full divide-y divide-gray-200">
          <thead className="bg-gray-50">
            <tr>
              <th scope="col" className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                {viewMode === 'country' ? 'Country' : 
                 viewMode === 'city' ? 'City' : 
                 viewMode === 'region' ? 'Region' : 'Continent'}
              </th>
              <th scope="col" className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                {viewMode === 'country' ? 'Continent' : 
                 viewMode === 'city' ? 'Location' : 
                 viewMode === 'region' ? 'Country' : 'Area'}
              </th>
              <th scope="col" className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                Visits
              </th>
              <th scope="col" className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                Unique Visitors
              </th>
              <th scope="col" className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                % of Total
              </th>
            </tr>
          </thead>
          <tbody className="bg-white divide-y divide-gray-200">
            {sortedData.length > 0 ? (
              sortedData.map((item, index) => (
                <tr key={index} className={index % 2 === 0 ? 'bg-white' : 'bg-gray-50'}>
                  <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900">
                    {getLocationValue(item)}
                    {item.location && (
                      <div className="text-xs text-gray-500 mt-1">{item.location}</div>
                    )}
                  </td>
                  <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
                    {getAreaValue(item)}
                  </td>
                  <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900">
                    {formatNumber(item.visits)}
                  </td>
                  <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900">
                    {formatNumber(item.visitors)}
                  </td>
                  <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900">
                    <div className="flex items-center">
                      <div className="w-24 bg-gray-200 rounded-full h-2">
                        <div
                          className="bg-blue-600 h-2 rounded-full"
                          style={{ width: `${item.percentage || 0}%` }}
                        />
                      </div>
                      <span className="ml-2">{formatPercent(item.percentage)}%</span>
                    </div>
                  </td>
                </tr>
              ))
            ) : (
              <tr>
                <td colSpan={5} className="px-6 py-4 text-center text-sm text-gray-500">
                  No location data available
                </td>
              </tr>
            )}
          </tbody>
        </table>
      </div>
    </div>
  );
} 