/**
 * TimeSafari Starred Plans Integration Example
 * 
 * Demonstrates how to integrate the Daily Notification Plugin's starred plans
 * management with the TimeSafari app's starred projects functionality.
 * 
 * This example shows:
 * 1. How to update starred plan IDs when users star/unstar projects
 * 2. How to sync starred plans on app startup
 * 3. How to verify stored plan IDs
 * 
 * @author Matthew Raymer
 * @version 1.0.0
 */

import { DailyNotification } from '@timesafari/daily-notification-plugin';
import { logger } from './logger'; // Assuming a logger utility

/**
 * TimeSafari Starred Plans Manager
 * 
 * Integrates with the Daily Notification Plugin to keep starred plan IDs
 * synchronized with the TimeSafari app's account settings.
 */
export class TimeSafariStarredPlansManager {
  private plugin: DailyNotification;
  private currentPlanIds: string[] = [];

  constructor(plugin: DailyNotification) {
    this.plugin = plugin;
  }

  /**
   * Sync starred plans from account settings to the plugin
   * 
   * Call this when:
   * - App starts up
   * - User logs in
   * - Account settings are refreshed
   * 
   * @param starredPlanHandleIds Array of plan handle IDs from account settings
   */
  async syncStarredPlansFromAccount(
    starredPlanHandleIds: string[]
  ): Promise<void> {
    try {
      logger.info('Syncing starred plans to plugin', {
        count: starredPlanHandleIds.length
      });

      // Update plugin with current starred plan IDs
      const result = await this.plugin.updateStarredPlans({
        planIds: starredPlanHandleIds
      });

      if (result.success) {
        this.currentPlanIds = starredPlanHandleIds;
        logger.info('Starred plans synced successfully', {
          count: result.planIdsCount,
          updatedAt: new Date(result.updatedAt).toISOString()
        });
      } else {
        logger.error('Failed to sync starred plans to plugin');
      }
    } catch (error) {
      logger.error('Error syncing starred plans', error);
      throw error;
    }
  }

  /**
   * Update starred plans when a user stars a project
   * 
   * Call this when:
   * - User clicks star on a project
   * - Star action completes successfully
   * 
   * @param planHandleId The plan handle ID that was starred
   */
  async addStarredPlan(planHandleId: string): Promise<void> {
    try {
      // Get current starred plans from plugin (to avoid duplicate updates)
      const current = await this.plugin.getStarredPlans();
      
      // Add new plan ID if not already present
      if (!current.planIds.includes(planHandleId)) {
        const updatedPlanIds = [...current.planIds, planHandleId];
        
        await this.plugin.updateStarredPlans({
          planIds: updatedPlanIds
        });
        
        this.currentPlanIds = updatedPlanIds;
        
        logger.info('Starred plan added', { planHandleId });
      } else {
        logger.debug('Plan already starred', { planHandleId });
      }
    } catch (error) {
      logger.error('Error adding starred plan', error);
      throw error;
    }
  }

  /**
   * Update starred plans when a user unstars a project
   * 
   * Call this when:
   * - User clicks unstar on a project
   * - Unstar action completes successfully
   * 
   * @param planHandleId The plan handle ID that was unstarred
   */
  async removeStarredPlan(planHandleId: string): Promise<void> {
    try {
      // Get current starred plans from plugin
      const current = await this.plugin.getStarredPlans();
      
      // Remove plan ID if present
      const updatedPlanIds = current.planIds.filter(
        id => id !== planHandleId
      );
      
      if (updatedPlanIds.length !== current.planIds.length) {
        await this.plugin.updateStarredPlans({
          planIds: updatedPlanIds
        });
        
        this.currentPlanIds = updatedPlanIds;
        
        logger.info('Starred plan removed', { planHandleId });
      } else {
        logger.debug('Plan not in starred list', { planHandleId });
      }
    } catch (error) {
      logger.error('Error removing starred plan', error);
      throw error;
    }
  }

  /**
   * Get current starred plans from plugin
   * 
   * Useful for verifying synchronization or displaying current state.
   * 
   * @returns Current starred plan IDs stored in the plugin
   */
  async getCurrentStarredPlans(): Promise<string[]> {
    try {
      const result = await this.plugin.getStarredPlans();
      this.currentPlanIds = result.planIds;
      return result.planIds;
    } catch (error) {
      logger.error('Error getting starred plans', error);
      throw error;
    }
  }

  /**
   * Verify starred plans synchronization
   * 
   * Compares account settings with plugin storage to ensure they match.
   * Useful for debugging or validation after sync operations.
   * 
   * @param accountPlanIds Plan IDs from account settings
   * @returns Object with sync status and any mismatches
   */
  async verifySync(accountPlanIds: string[]): Promise<{
    inSync: boolean;
    accountCount: number;
    pluginCount: number;
    mismatches: {
      inAccountNotPlugin: string[];
      inPluginNotAccount: string[];
    };
  }> {
    try {
      const pluginResult = await this.plugin.getStarredPlans();
      const pluginPlanIds = pluginResult.planIds;

      const inAccountNotPlugin = accountPlanIds.filter(
        id => !pluginPlanIds.includes(id)
      );
      const inPluginNotAccount = pluginPlanIds.filter(
        id => !accountPlanIds.includes(id)
      );

      const inSync =
        inAccountNotPlugin.length === 0 && inPluginNotAccount.length === 0;

      return {
        inSync,
        accountCount: accountPlanIds.length,
        pluginCount: pluginPlanIds.length,
        mismatches: {
          inAccountNotPlugin,
          inPluginNotAccount
        }
      };
    } catch (error) {
      logger.error('Error verifying sync', error);
      throw error;
    }
  }
}

/**
 * Example integration with TimeSafari's searchStarred method
 * 
 * This shows how to integrate the starred plans manager with the existing
 * TimeSafari searchStarred method.
 */
export async function integrateWithSearchStarred(
  plugin: DailyNotification,
  accountSettings: { starredPlanHandleIds?: string[] }
): Promise<void> {
  const manager = new TimeSafariStarredPlansManager(plugin);

  try {
    // Get starred plan IDs from account settings
    const starredIds = accountSettings.starredPlanHandleIds || [];

    if (starredIds.length === 0) {
      logger.info('No starred plans to sync');
      return;
    }

    // Sync to plugin
    await manager.syncStarredPlansFromAccount(starredIds);

    // Verify sync (optional, for debugging)
    const syncStatus = await manager.verifySync(starredIds);
    if (!syncStatus.inSync) {
      logger.warn('Starred plans sync verification failed', syncStatus);
      // Optionally retry sync if verification fails
      await manager.syncStarredPlansFromAccount(starredIds);
    } else {
      logger.info('Starred plans sync verified');
    }
  } catch (error) {
    logger.error('Error integrating with searchStarred', error);
    // Don't throw - allow searchStarred to continue even if plugin sync fails
  }
}

/**
 * Example: Hook into star/unstar actions
 * 
 * This shows how to update the plugin when users star or unstar projects.
 */
export async function handleStarAction(
  plugin: DailyNotification,
  planHandleId: string,
  isStarring: boolean
): Promise<void> {
  const manager = new TimeSafariStarredPlansManager(plugin);

  try {
    if (isStarring) {
      await manager.addStarredPlan(planHandleId);
    } else {
      await manager.removeStarredPlan(planHandleId);
    }
  } catch (error) {
    logger.error('Error handling star action', error);
    // Don't throw - allow star action to complete even if plugin update fails
  }
}

