/* eslint-disable @typescript-eslint/no-explicit-any */
/**
 * TimeSafari Platform Service Mixin
 * 
 * TypeScript mixin for TimeSafari Daily Notification Plugin integration.
 * Provides type-safe service integration for Vue components and other frameworks.
 * 
 * @author Matthew Raymer
 * @version 1.0.0
 */

import { DailyNotificationService, DailyNotificationServiceConfig } from '../services/DailyNotificationService';

/**
 * TimeSafari Daily Notification Mixin Interface
 */
export interface TimeSafariDailyNotificationMixin {
  // Service instance
  dailyNotificationService: DailyNotificationService;
  
  // Service methods
  initializeDailyNotifications(config: DailyNotificationServiceConfig): Promise<void>;
  scheduleDailyNotification(options: {
    title: string;
    body: string;
    time: string;
    channel?: string;
    actions?: Array<{ id: string; title: string }>;
  }): Promise<void>;
  fetchCommunityData(): Promise<unknown>;
  getServiceStatus(): unknown;
  shutdownDailyNotifications(): Promise<void>;
}

/**
 * TimeSafari Daily Notification Mixin Implementation
 */
export class TimeSafariDailyNotificationMixin implements TimeSafariDailyNotificationMixin {
  // Service instance
  public dailyNotificationService: DailyNotificationService = DailyNotificationService.getInstance();
  
  // Reactive state
  private _serviceInitialized = false;
  private _serviceError: string | null = null;
  private _serviceStatus: unknown = null;
  
  /**
   * Initialize daily notification service
   */
  async initializeDailyNotifications(config: DailyNotificationServiceConfig): Promise<void> {
    try {
      await this.dailyNotificationService.initialize(config);
      this._serviceInitialized = true;
      this._serviceError = null;
      this._serviceStatus = this.dailyNotificationService.getStatus();
      
    } catch (error) {
      this._serviceError = (error as Error).message;
      this._serviceInitialized = false;
      throw error;
    }
  }
  
  /**
   * Schedule a daily notification
   */
  async scheduleDailyNotification(options: {
    title: string;
    body: string;
    time: string;
    channel?: string;
    actions?: Array<{ id: string; title: string }>;
  }): Promise<void> {
    if (!this._serviceInitialized) {
      throw new Error('Daily notification service not initialized');
    }
    
    try {
      await this.dailyNotificationService.scheduleDailyNotification(options);
    } catch (error) {
      this._serviceError = (error as Error).message;
      throw error;
    }
  }
  
  /**
   * Fetch community data
   */
  async fetchCommunityData(): Promise<unknown> {
    if (!this._serviceInitialized) {
      throw new Error('Daily notification service not initialized');
    }
    
    try {
      const data = await this.dailyNotificationService.fetchCommunityData();
      return data;
    } catch (error) {
      this._serviceError = (error as Error).message;
      throw error;
    }
  }
  
  /**
   * Get service status
   */
  getServiceStatus(): unknown {
    if (!this._serviceInitialized) {
      return null;
    }
    
    this._serviceStatus = this.dailyNotificationService.getStatus();
    return this._serviceStatus;
  }
  
  /**
   * Shutdown daily notification service
   */
  async shutdownDailyNotifications(): Promise<void> {
    if (!this._serviceInitialized) {
      return;
    }
    
    try {
      await this.dailyNotificationService.shutdown();
      this._serviceInitialized = false;
      this._serviceError = null;
      this._serviceStatus = null;
    } catch (error) {
      this._serviceError = (error as Error).message;
      throw error;
    }
  }
  
  /**
   * Get service ready status
   */
  isServiceReady(): boolean {
    return this._serviceInitialized;
  }
  
  /**
   * Get service status
   */
  getServiceStatusData(): unknown {
    return this._serviceStatus;
  }
  
  /**
   * Get service error
   */
  getServiceError(): string | null {
    return this._serviceError;
  }
}

/**
 * Type-safe decorator for components
 */
export function WithTimeSafariDailyNotifications<T extends Constructor>(Base: T): T {
  return class extends Base {
    public dailyNotificationService: DailyNotificationService = DailyNotificationService.getInstance();
    private _serviceInitialized = false;
    private _serviceError: string | null = null;
    private _serviceStatus: unknown = null;
    
    async initializeDailyNotifications(config: DailyNotificationServiceConfig): Promise<void> {
      try {
        await this.dailyNotificationService.initialize(config);
        this._serviceInitialized = true;
        this._serviceError = null;
        this._serviceStatus = this.dailyNotificationService.getStatus();
      } catch (error) {
        this._serviceError = (error as Error).message;
        this._serviceInitialized = false;
        throw error;
      }
    }
    
    async scheduleDailyNotification(options: {
      title: string;
      body: string;
      time: string;
      channel?: string;
      actions?: Array<{ id: string; title: string }>;
    }): Promise<void> {
      if (!this._serviceInitialized) {
        throw new Error('Daily notification service not initialized');
      }
      
      try {
        await this.dailyNotificationService.scheduleDailyNotification(options);
      } catch (error) {
        this._serviceError = (error as Error).message;
        throw error;
      }
    }
    
    async fetchCommunityData(): Promise<unknown> {
      if (!this._serviceInitialized) {
        throw new Error('Daily notification service not initialized');
      }
      
      try {
        const data = await this.dailyNotificationService.fetchCommunityData();
        return data;
      } catch (error) {
        this._serviceError = (error as Error).message;
        throw error;
      }
    }
    
    getServiceStatus(): unknown {
      if (!this._serviceInitialized) {
        return null;
      }
      
      this._serviceStatus = this.dailyNotificationService.getStatus();
      return this._serviceStatus;
    }
    
    async shutdownDailyNotifications(): Promise<void> {
      if (!this._serviceInitialized) {
        return;
      }
      
      try {
        await this.dailyNotificationService.shutdown();
        this._serviceInitialized = false;
        this._serviceError = null;
        this._serviceStatus = null;
      } catch (error) {
        this._serviceError = (error as Error).message;
        throw error;
      }
    }
    
    isServiceReady(): boolean {
      return this._serviceInitialized;
    }
    
    getServiceStatusData(): unknown {
      return this._serviceStatus;
    }
    
    getServiceError(): string | null {
      return this._serviceError;
    }
  };
}

/**
 * Constructor type for components
 * Note: any[] is required for TypeScript mixin pattern compatibility.
 * TypeScript's mixin pattern requires any[] for constructor arguments.
 * This is a TypeScript limitation, not a design choice.
 */
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type Constructor<T = Record<string, unknown>> = new (...args: any[]) => T;

/**
 * Example component using the mixin
 */
export class TimeSafariDailyNotificationExample extends TimeSafariDailyNotificationMixin {
  private activeDid = 'did:example:timesafari-user-123';
  
  async initialize(): Promise<void> {
    try {
      // Initialize the service
      await this.initializeDailyNotifications({
        activeDid: this.activeDid,
        platform: 'android',
        logging: {
          level: 'info',
          enableStructuredLogging: true,
          enableEventIds: true,
          enablePerformanceMetrics: true
        }
      });
      
      // Schedule a daily notification
      await this.scheduleDailyNotification({
        title: 'TimeSafari Community Update',
        body: 'New offers and project updates available',
        time: '09:00',
        channel: 'timesafari_community_updates'
      });
      
    } catch (error) {
      throw new Error(`Failed to initialize daily notifications: ${error}`);
    }
  }
  
  async handleFetchCommunityData(): Promise<void> {
    try {
      await this.fetchCommunityData();
      // Community data fetched successfully
    } catch (error) {
      throw new Error(`Failed to fetch community data: ${error}`);
    }
  }
  
  get serviceReady(): boolean {
    return this.isServiceReady();
  }
  
  get serviceStatus(): unknown {
    return this.getServiceStatusData();
  }
  
  get serviceError(): string | null {
    return this.getServiceError();
  }
}