import { DateTime } from "luxon";
import { AccessToken, WebhookConfig } from "@/types";
import { planetCalculations } from "@/planets";

export class NotificationService {
  private notificationState = new Map<string, boolean>();
  private lastWebhookTime = 0;
  private readonly WEBHOOK_COOLDOWN = 5000; // 5 seconds between webhooks

  public checkAndNotify = async (
    characters: AccessToken[],
    webhookConfig: WebhookConfig
  ): Promise<void> => {
    if (!webhookConfig.enabled) return;

    const notifications: string[] = [];
    const now = DateTime.now();

    for (const character of characters) {
      for (const planet of character.planets) {
        const planetDetails = planetCalculations(planet);
        
        // Check extractors for expiry warnings
        for (const extractor of planetDetails.extractors) {
          if (extractor.expiry_time) {
            const expiryTime = DateTime.fromISO(extractor.expiry_time);
            const identifier = `${character.character.name}-${planet.planet_id}-${extractor.pin_id}`;
            
            // Check if already expired
            if (expiryTime <= now) {
              if (!this.notificationState.get(`${identifier}-expired`)) {
                notifications.push(`🚨 EXTRACTOR EXPIRED - ${character.character.name} Planet ${planet.planet_id}`);
                this.notificationState.set(`${identifier}-expired`, true);
              }
            } else {
              // Check if expiring soon (within the warning threshold)
              const warningThreshold = this.parseDuration(webhookConfig.expiryThreshold || "P12H");
              const warningTime = now.plus(warningThreshold);
              
              if (expiryTime <= warningTime && expiryTime > now) {
                if (!this.notificationState.get(`${identifier}-warning`)) {
                  const hoursLeft = Math.round(expiryTime.diff(now, "hours").hours);
                  notifications.push(`⚠️ EXTRACTOR EXPIRING SOON - ${character.character.name} Planet ${planet.planet_id} (${hoursLeft}h left)`);
                  this.notificationState.set(`${identifier}-warning`, true);
                }
              }
            }
          }
        }

        // Check storage capacity
        for (const storage of planetDetails.storageInfo) {
          const identifier = `${character.character.name}-${planet.planet_id}-${storage.type_id}`;
          
          if (storage.fillRate >= (webhookConfig.storageCriticalThreshold || 100)) {
            if (!this.notificationState.get(`${identifier}-critical`)) {
              notifications.push(`🚨 STORAGE CRITICAL - ${character.character.name} Planet ${planet.planet_id} (${storage.fillRate.toFixed(1)}%)`);
              this.notificationState.set(`${identifier}-critical`, true);
            }
          } else if (storage.fillRate >= (webhookConfig.storageWarningThreshold || 85)) {
            if (!this.notificationState.get(`${identifier}-warning`)) {
              notifications.push(`⚠️ STORAGE WARNING - ${character.character.name} Planet ${planet.planet_id} (${storage.fillRate.toFixed(1)}%)`);
              this.notificationState.set(`${identifier}-warning`, true);
            }
          }
        }
      }
    }

    if (notifications.length > 0) {
      await this.sendWebhook(notifications.join("\n"));
    }
  };

  private parseDuration(duration: string): any {
    // Parse ISO 8601 duration (e.g., "P12H", "P1D", "PT2H30M")
    try {
      return DateTime.fromISO(`2000-01-01T00:00:00Z`).plus({ [duration.slice(-1) === 'H' ? 'hours' : duration.slice(-1) === 'D' ? 'days' : 'minutes' ]: parseInt(duration.slice(1, -1)) }).diff(DateTime.fromISO(`2000-01-01T00:00:00Z`));
    } catch {
      // Default to 12 hours if parsing fails
      return { hours: 12 };
    }
  }

  private sendWebhook = async (content: string): Promise<void> => {
    try {
      const response = await fetch("/api/webhook", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ content }),
      });

      if (!response.ok) {
        throw new Error(`Webhook failed: ${response.status}`);
      }
    } catch (error) {
      console.error("Webhook error:", error);
    }
  };
}

export const notificationService = new NotificationService();
