/**
 * DailyNotification Setup for TimeSafari PWA
 * 
 * This example shows exactly how to configure the DailyNotification plugin
 * to work with your existing TimeSafari PWA request patterns, specifically
 * the loadNewStarredProjectChanges() and getStarredProjectsWithChanges() methods.
 * 
 * @author Matthew Raymer
 * @version 1.0.0
 */

import { DailyNotification } from '@timesafari/daily-notification-plugin';
import { TimeSafariIntegrationService } from '@timesafari/daily-notification-plugin';
import { AxiosInstance } from 'axios';

// Your existing TimeSafari PWA interfaces
interface PlanSummaryAndPreviousClaim {
  id: string;
  title: string;
  description: string;
  lastUpdated: string;
  previousClaim?: unknown;
}

interface StarredProjectsResponse {
  data: Array<PlanSummaryAndPreviousClaim>;
  hitLimit: boolean;
}

// Your existing TimeSafari PWA class structure
class TimeSafariHomeView {
  // Your existing properties
  activeDid = '';
  starredPlanHandleIds: string[] = [];
  lastAckedStarredPlanChangesJwtId = '';
  numNewStarredProjectChanges = 0;
  newStarredProjectChangesHitLimit = false;
  apiServer = 'https://endorser.ch';
  axios: AxiosInstance;
  
  // Plugin integration
  private dailyNotificationService: DailyNotification | null = null;
  private integrationService: TimeSafariIntegrationService | null = null;
  
  constructor(axiosInstance: AxiosInstance) {
    this.axios = axiosInstance;
  }
  
  /**
   * DailyNotification Setup - This is what you need to add to your TimeSafari PWA
   */
  async setupDailyNotification(): Promise<void> {
    try {
      // Setup DailyNotification for TimeSafari PWA
      
      // Step 1: Configure the DailyNotification plugin
      await DailyNotification.configure({
        // Basic plugin configuration
        storage: 'tiered',
        ttlSeconds: 1800,
        enableETagSupport: true,
        enableErrorHandling: true,
        enablePerformanceOptimization: true,
        
        // TimeSafari-specific configuration
        timesafariConfig: {
          // Required: Your existing activeDid
          activeDid: this.activeDid,
          
          // Your existing API endpoints
          endpoints: {
            offersToPerson: `${this.apiServer}/api/v2/offers/person`,
            offersToPlans: `${this.apiServer}/api/v2/offers/plans`,
            projectsLastUpdated: `${this.apiServer}/api/v2/report/plansLastUpdatedBetween`
          },
          
          // Configure starred projects fetching (matches your existing pattern)
          starredProjectsConfig: {
            enabled: true,
            starredPlanHandleIds: this.starredPlanHandleIds,
            lastAckedJwtId: this.lastAckedStarredPlanChangesJwtId,
            fetchInterval: '0 8 * * *',  // Daily at 8 AM (same as your existing schedule)
            maxResults: 50,
            hitLimitHandling: 'warn'  // Same as your existing error handling
          },
          
          // Sync configuration (optimized for your use case)
          syncConfig: {
            enableParallel: true,
            maxConcurrent: 3,
            batchSize: 10,
            timeout: 30000,
            retryAttempts: 3
          },
          
          // Error policy (matches your existing error handling)
          errorPolicy: {
            maxRetries: 3,
            backoffMultiplier: 2,
            activeDidChangeRetries: 5,
            starredProjectsRetries: 3
          }
        },
        
        // Network configuration using your existing axios instance
        networkConfig: {
          // Use your existing axios instance
          httpClient: this.axios,
          baseURL: this.apiServer,
          timeout: 30000,
          retryAttempts: 3,
          retryDelay: 1000,
          maxConcurrent: 5,
          
          // Headers matching your existing pattern
          defaultHeaders: {
            'Content-Type': 'application/json',
            'Accept': 'application/json',
            'User-Agent': 'TimeSafari-PWA/1.0.0'
          }
        },
        
        // Content fetch configuration (replaces your existing loadNewStarredProjectChanges)
        contentFetch: {
          enabled: true,
          schedule: '0 8 * * *',  // Daily at 8 AM
          
          // Your existing request pattern
          requestConfig: {
            method: 'POST',
            url: `${this.apiServer}/api/v2/report/plansLastUpdatedBetween`,
            headers: {
              'Authorization': 'Bearer ${jwt}',
              'X-User-DID': '${activeDid}',
              'Content-Type': 'application/json'
            },
            body: {
              planIds: '${starredPlanHandleIds}',
              afterId: '${lastAckedJwtId}'
            }
          },
          
          // Callbacks that match your existing error handling
          callbacks: {
            onSuccess: this.handleStarredProjectsSuccess.bind(this),
            onError: this.handleStarredProjectsError.bind(this),
            onComplete: this.handleStarredProjectsComplete.bind(this)
          }
        },
        
        // Authentication configuration
        authentication: {
          jwt: {
            secret: process.env.JWT_SECRET || 'your-jwt-secret',
            algorithm: 'HS256',
            expirationMinutes: 60,
            refreshThresholdMinutes: 10
          }
        },
        
        // Observability configuration
        logging: {
          level: 'INFO',
          enableRequestLogging: true,
          enableResponseLogging: true,
          enableErrorLogging: true,
          redactSensitiveData: true
        },
        
        // Security configuration
        security: {
          certificatePinning: {
            enabled: true,
            pins: [
              {
                hostname: 'endorser.ch',
                pins: ['sha256/YOUR_PIN_HERE']
              }
            ]
          }
        }
      });
      
      // Step 2: Initialize TimeSafari Integration Service
      this.integrationService = TimeSafariIntegrationService.getInstance();
      await this.integrationService.initialize({
        activeDid: this.activeDid,
        storageAdapter: this.getTimeSafariStorageAdapter(),
        endorserApiBaseUrl: this.apiServer,
        
        // Use your existing request patterns
        requestConfig: {
          httpClient: this.axios,
          baseURL: this.apiServer,
          timeout: 30000,
          retryAttempts: 3
        },
        
        // Configure starred projects fetching
        starredProjectsConfig: {
          enabled: true,
          starredPlanHandleIds: this.starredPlanHandleIds,
          lastAckedJwtId: this.lastAckedStarredPlanChangesJwtId,
          fetchInterval: '0 8 * * *',
          maxResults: 50
        }
      });
      
      // Step 3: Schedule daily notifications
      await DailyNotification.scheduleDailyNotification({
        title: 'TimeSafari Community Update',
        body: 'You have new offers and project updates',
        time: '09:00',
        channel: 'timesafari_community_updates'
      });
      
      // DailyNotification setup completed successfully
      
    } catch (error) {
      console.error('Failed to setup DailyNotification:', error);
      throw error;
    }
  }
  
  /**
   * Enhanced version of your existing loadNewStarredProjectChanges method
   * 
   * This replaces your existing method with plugin-enhanced functionality
   * while maintaining the same interface and behavior.
   */
  async loadNewStarredProjectChanges(): Promise<void> {
    if (this.activeDid && this.starredPlanHandleIds.length > 0) {
      try {
        // Use plugin's enhanced fetching with same interface as your existing code
        const starredProjectChanges = await this.integrationService?.getStarredProjectsWithChanges(
          this.activeDid,
          this.starredPlanHandleIds,
          this.lastAckedStarredPlanChangesJwtId
        );
        
        if (!starredProjectChanges) {
          this.numNewStarredProjectChanges = 0;
          this.newStarredProjectChangesHitLimit = false;
          return;
        }
        
        // Same handling as your existing code
        this.numNewStarredProjectChanges = starredProjectChanges.data.length;
        this.newStarredProjectChangesHitLimit = starredProjectChanges.hitLimit;
        
        // Enhanced logging (optional)
        // Starred projects loaded successfully
        
      } catch (error) {
        // Same error handling as your existing code
        console.warn('[HomeView] Failed to load starred project changes:', error);
        this.numNewStarredProjectChanges = 0;
        this.newStarredProjectChangesHitLimit = false;
      }
    } else {
      this.numNewStarredProjectChanges = 0;
      this.newStarredProjectChangesHitLimit = false;
    }
  }
  
  /**
   * Callback handlers that match your existing error handling patterns
   */
  async handleStarredProjectsSuccess(data: StarredProjectsResponse): Promise<void> {
    // Same handling as your existing code
    this.numNewStarredProjectChanges = data.data.length;
    this.newStarredProjectChangesHitLimit = data.hitLimit;
    
    // Update UI (your existing method)
    this.updateStarredProjectsUI(data);
    
    // Enhanced logging (optional)
    // Starred projects success callback
  }
  
  async handleStarredProjectsError(error: Error): Promise<void> {
    // Same error handling as your existing code
    console.warn('[HomeView] Failed to load starred project changes:', error);
    this.numNewStarredProjectChanges = 0;
    this.newStarredProjectChangesHitLimit = false;
    
    // Enhanced error handling (optional)
    console.error('Starred projects error callback:', {
      error: error.message,
      activeDid: this.activeDid,
      planCount: this.starredPlanHandleIds.length
    });
  }
  
  async handleStarredProjectsComplete(_result: unknown): Promise<void> {
    // Handle completion
    // Starred projects fetch completed
  }
  
  /**
   * Your existing methods (unchanged)
   */
  private updateStarredProjectsUI(_data: StarredProjectsResponse): void {
    // Your existing UI update logic
    // Updating UI with starred projects data
  }
  
  private getTimeSafariStorageAdapter(): unknown {
    // Return your existing TimeSafari storage adapter
    return {
      // Your existing storage adapter implementation
    };
  }
}

// Usage example - This is what you add to your TimeSafari PWA
export async function setupDailyNotificationForTimeSafari(
  axiosInstance: AxiosInstance,
  activeDid: string,
  starredPlanHandleIds: string[],
  lastAckedJwtId: string,
  apiServer = 'https://endorser.ch'
): Promise<TimeSafariHomeView> {
  
  // Setting up DailyNotification for TimeSafari PWA
  
  // Create your existing HomeView instance
  const homeView = new TimeSafariHomeView(axiosInstance);
  
  // Set up your existing TimeSafari data
  homeView.activeDid = activeDid;
  homeView.starredPlanHandleIds = starredPlanHandleIds;
  homeView.lastAckedStarredPlanChangesJwtId = lastAckedJwtId;
  homeView.apiServer = apiServer;
  
  // Setup DailyNotification plugin
  await homeView.setupDailyNotification();
  
  // Test the enhanced method
  await homeView.loadNewStarredProjectChanges();
  
  // DailyNotification setup completed successfully
  
  return homeView;
}

// Vue.js component integration example
export const TimeSafariDailyNotificationMixin = {
  data(): Record<string, unknown> {
    return {
      // Your existing data
      activeDid: '',
      starredPlanHandleIds: [] as string[],
      lastAckedStarredPlanChangesJwtId: '',
      numNewStarredProjectChanges: 0,
      newStarredProjectChangesHitLimit: false,
      
      // Plugin integration
      dailyNotificationService: null as DailyNotification | null,
      integrationService: null as TimeSafariIntegrationService | null
    };
  },
  
  async mounted(): Promise<void> {
    // Setup DailyNotification when component mounts
    await this.setupDailyNotification();
  },
  
  methods: {
    async setupDailyNotification(): Promise<void> {
      try {
        // Configure DailyNotification plugin
        await DailyNotification.configure({
          timesafariConfig: {
            activeDid: this.activeDid,
            endpoints: {
              projectsLastUpdated: `${this.apiServer}/api/v2/report/plansLastUpdatedBetween`
            },
            starredProjectsConfig: {
              enabled: true,
              starredPlanHandleIds: this.starredPlanHandleIds,
              lastAckedJwtId: this.lastAckedStarredPlanChangesJwtId,
              fetchInterval: '0 8 * * *'
            }
          },
          
          networkConfig: {
            httpClient: this.axios,
            baseURL: this.apiServer,
            timeout: 30000
          },
          
          contentFetch: {
            enabled: true,
            schedule: '0 8 * * *',
            callbacks: {
              onSuccess: this.handleStarredProjectsSuccess,
              onError: this.handleStarredProjectsError
            }
          }
        });
        
        // Initialize integration service
        this.integrationService = TimeSafariIntegrationService.getInstance();
        await this.integrationService.initialize({
          activeDid: this.activeDid,
          storageAdapter: this.getTimeSafariStorageAdapter(),
          endorserApiBaseUrl: this.apiServer
        });
        
      } catch (error) {
        console.error('Failed to setup DailyNotification:', error);
      }
    },
    
    // Your existing methods (enhanced)
    async loadNewStarredProjectChanges(): Promise<void> {
      if (this.activeDid && this.starredPlanHandleIds.length > 0) {
        try {
          const starredProjectChanges = await this.integrationService.getStarredProjectsWithChanges(
            this.activeDid,
            this.starredPlanHandleIds,
            this.lastAckedStarredPlanChangesJwtId
          );
          
          this.numNewStarredProjectChanges = starredProjectChanges.data.length;
          this.newStarredProjectChangesHitLimit = starredProjectChanges.hitLimit;
          
        } catch (error) {
          console.warn('[HomeView] Failed to load starred project changes:', error);
          this.numNewStarredProjectChanges = 0;
          this.newStarredProjectChangesHitLimit = false;
        }
      } else {
        this.numNewStarredProjectChanges = 0;
        this.newStarredProjectChangesHitLimit = false;
      }
    },
    
    handleStarredProjectsSuccess(data: StarredProjectsResponse): void {
      this.numNewStarredProjectChanges = data.data.length;
      this.newStarredProjectChangesHitLimit = data.hitLimit;
      this.updateStarredProjectsUI(data);
    },
    
    handleStarredProjectsError(error: Error): void {
      console.warn('[HomeView] Failed to load starred project changes:', error);
      this.numNewStarredProjectChanges = 0;
      this.newStarredProjectChangesHitLimit = false;
    },
    
    // Your existing methods
    updateStarredProjectsUI(_data: StarredProjectsResponse): void {
      // Your existing UI update logic
    },
    
    getTimeSafariStorageAdapter(): unknown {
      // Your existing storage adapter
      return {};
    }
  }
};

// Export for use in your TimeSafari PWA
export { TimeSafariHomeView };
