
import { pb } from '@/lib/pocketbase';
import { UptimeData } from '@/types/service.types';

const uptimeCache = new Map<string, {
  data: UptimeData[],
  timestamp: number,
  expiresIn: number
}>();

const CACHE_TTL = 3000; // 3 seconds for faster updates

// Map service types to their corresponding collections
const getCollectionForServiceType = (serviceType: string): string => {
  const type = serviceType.toLowerCase();
  switch (type) {
    case 'ping':
    case 'icmp':
      return 'ping_data';
    case 'dns':
      return 'dns_data';
    case 'tcp':
      return 'tcp_data';
    case 'http':
    case 'https':
    default:
      return 'uptime_data';
  }
};

export const uptimeService = {
  async recordUptimeData(data: UptimeData): Promise<void> {
    try {
      console.log(`Recording uptime data for service ${data.serviceId || data.service_id}: Status ${data.status}, Response time: ${data.responseTime}ms`);
      
      const options = {
        $autoCancel: false,
        $cancelKey: `uptime_record_${data.serviceId || data.service_id}_${Date.now()}`
      };
      
      const record = await pb.collection('uptime_data').create({
        service_id: data.service_id || data.serviceId,
        timestamp: data.timestamp,
        status: data.status,
        response_time: data.responseTime
      }, options);
      
      // Invalidate cache for this service
      const serviceId = data.service_id || data.serviceId;
      const keysToDelete = Array.from(uptimeCache.keys()).filter(key => key.includes(`uptime_${serviceId}`));
      keysToDelete.forEach(key => uptimeCache.delete(key));
      
      console.log(`Uptime data recorded successfully with ID: ${record.id}`);
    } catch (error) {
      console.error("Error recording uptime data:", error);
      throw new Error(`Failed to record uptime data: ${error}`);
    }
  },
  
  async getUptimeHistory(
    serviceId: string, 
    limit: number = 200, 
    startDate?: Date, 
    endDate?: Date,
    serviceType?: string
  ): Promise<UptimeData[]> {
    try {
      if (!serviceId) {
        console.log('No serviceId provided to getUptimeHistory');
        return [];
      }

      const cacheKey = `uptime_${serviceId}_${limit}_${startDate?.toISOString() || ''}_${endDate?.toISOString() || ''}_${serviceType || 'default'}_default`;
      
      // Check cache
      const cached = uptimeCache.get(cacheKey);
      if (cached && (Date.now() - cached.timestamp) < cached.expiresIn) {
        console.log(`Using cached uptime history for service ${serviceId}`);
        return cached.data;
      }
      
      // Determine the correct collection based on service type
      const collection = serviceType ? getCollectionForServiceType(serviceType) : 'uptime_data';
      console.log(`Fetching default uptime history for service ${serviceId} from collection ${collection}, limit: ${limit}`);
      
      // Build filter to get records for specific service_id
      let filter = `service_id='${serviceId}'`;
      
      // Add date range filtering if provided
      if (startDate && endDate) {
        const startUTC = startDate.toISOString();
        const endUTC = endDate.toISOString();
        
        console.log(`Date filter: ${startUTC} to ${endUTC}`);
        filter += ` && timestamp >= "${startUTC}" && timestamp <= "${endUTC}"`;
      }
      
      const options = {
        filter: filter,
        sort: '-timestamp', // Sort by timestamp descending (newest first)
        $autoCancel: false,
        $cancelKey: `uptime_history_${serviceId}_${Date.now()}`
      };
      
      console.log(`Filter query for default data: ${filter} on collection: ${collection}`);
      
      const response = await pb.collection(collection).getList(1, limit, options);
      
      console.log(`Fetched ${response.items.length} records for service ${serviceId} from ${collection}`);
      
      if (response.items.length > 0) {
        console.log(`Date range in results: ${response.items[response.items.length - 1].timestamp} to ${response.items[0].timestamp}`);
      } else {
        console.log(`No records found for service_id '${serviceId}' in collection: ${collection}`);
      }
      
      // Transform the response items to UptimeData format
      const uptimeData = response.items.map(item => ({
        id: item.id,
        service_id: item.service_id,
        serviceId: item.service_id,
        timestamp: item.timestamp,
        status: item.status as "up" | "down" | "warning" | "paused",
        responseTime: item.response_time || 0,
        date: item.timestamp,
        uptime: 100,
        error_message: item.error_message,
        details: item.details
      }));
      
      // Cache the result
      uptimeCache.set(cacheKey, {
        data: uptimeData,
        timestamp: Date.now(),
        expiresIn: CACHE_TTL
      });
      
      return uptimeData;
    } catch (error) {
      console.error(`Error fetching uptime history for service ${serviceId}:`, error);
      
      // Try to return cached data as fallback
      const cacheKey = `uptime_${serviceId}_${limit}_${startDate?.toISOString() || ''}_${endDate?.toISOString() || ''}_${serviceType || 'default'}_default`;
      const cached = uptimeCache.get(cacheKey);
      if (cached) {
        console.log(`Using expired cached data for service ${serviceId} due to fetch error`);
        return cached.data;
      }
      
      // Return empty array instead of throwing to prevent UI crashes
      console.log(`Returning empty array for service ${serviceId} due to fetch error`);
      return [];
    }
  },

  async getUptimeHistoryByRegionalAgent(
    serviceId: string, 
    limit: number = 50, 
    startDate?: Date, 
    endDate?: Date, 
    serviceType?: string,
    regionName?: string,
    agentId?: string
  ): Promise<UptimeData[]> {
    try {
      if (!regionName || !agentId) {
        console.log('No region name or agent ID provided for regional query');
        return [];
      }

      const cacheKey = `uptime_${serviceId}_${limit}_${startDate?.toISOString() || ''}_${endDate?.toISOString() || ''}_${serviceType || 'default'}_${regionName}_${agentId}`;
      
      // Check cache
      const cached = uptimeCache.get(cacheKey);
      if (cached && (Date.now() - cached.timestamp) < cached.expiresIn) {
        console.log(`Using cached regional uptime history for service ${serviceId}`);
        return cached.data;
      }

      // Determine the correct collection based on service type
      const collection = serviceType ? getCollectionForServiceType(serviceType) : 'uptime_data';
      console.log(`Fetching regional uptime history from collection: ${collection} for service: ${serviceId}, region: ${regionName}, agent: ${agentId}`);

      // Build filter for regional agent data
      let filter = `service_id="${serviceId}" && region_name="${regionName}" && agent_id="${agentId}"`;

      if (startDate && endDate) {
        const startISO = startDate.toISOString();
        const endISO = endDate.toISOString();
        filter += ` && timestamp>="${startISO}" && timestamp<="${endISO}"`;
      }

      console.log(`Regional filter query: ${filter} on collection: ${collection}`);

      const records = await pb.collection(collection).getList(1, limit, {
        sort: '-timestamp',
        filter: filter,
        $autoCancel: false,
        $cancelKey: `regional_uptime_history_${serviceId}_${Date.now()}`
      });

      console.log(`Retrieved ${records.items.length} regional uptime records from ${collection} for region ${regionName}, agent ${agentId}`);

      const uptimeData = records.items.map(item => ({
        id: item.id,
        service_id: item.service_id,
        serviceId: item.service_id,
        timestamp: item.timestamp,
        status: item.status as "up" | "down" | "paused" | "warning",
        responseTime: item.response_time || item.responseTime || 0,
        error_message: item.error_message,
        details: item.details,
        created: item.created,
        updated: item.updated
      }));

      // Cache the result
      uptimeCache.set(cacheKey, {
        data: uptimeData,
        timestamp: Date.now(),
        expiresIn: CACHE_TTL
      });

      return uptimeData;
    } catch (error) {
      const collectionForError = serviceType ? getCollectionForServiceType(serviceType) : 'uptime_data';
      console.error(`Error fetching regional uptime history from ${collectionForError}:`, error);
      return [];
    }
  }
};