/**
 * React hook for managing custom XBRL concept mappings specific to earnings data.
 */

import { useCallback } from 'react';
import { useMappings } from './useMappings';
import { createMapping } from '../types/mappings';
import type {
  CustomXbrlConceptMapping,
  CustomConcept,
  MappingScope,
  TargetField,
} from '../types/mappings';
import type { Frequency } from '../types/financial';

/**
 * Information about a cell that can be mapped.
 */
export interface MappingCellInfo {
  /** The metric key (e.g., "totalRevenues") */
  metricKey: string;
  /** The display label for the metric (e.g., "Total Revenues") */
  metricLabel: string;
  /** The period label (e.g., "2024", "2024Q1") */
  periodLabel: string;
}

/**
 * Context information for an earnings mapping.
 */
export interface EarningsMappingContext {
  /** Ticker symbol */
  symbol: string;
  /** Reporting frequency */
  frequency: Frequency;
  /** Earliest period being displayed */
  earliestPeriod?: string;
  /** Latest period being displayed */
  latestPeriod?: string;
}

/**
 * Result of the useEarningsMappings hook.
 */
export interface UseEarningsMappingsResult {
  /** All custom mappings */
  mappings: CustomXbrlConceptMapping[];
  /** Whether data is being loaded */
  isLoading: boolean;
  /** Error that occurred during operations */
  error: Error | null;
  /** Add a new mapping */
  addMapping: (mapping: CustomXbrlConceptMapping) => Promise<void>;
  /** Update an existing mapping */
  updateMapping: (id: string, mapping: CustomXbrlConceptMapping) => Promise<void>;
  /** Delete a mapping */
  deleteMapping: (id: string) => Promise<void>;
  /** Toggle the enabled state of a mapping */
  toggleMapping: (id: string) => Promise<void>;
  /** Import mappings from JSON */
  importMappings: (json: string) => Promise<void>;
  /** Export mappings to JSON */
  exportMappings: () => Promise<string>;
  /** Reload all mappings */
  reload: () => Promise<void>;
  /**
   * Create a mapping from earnings context with pre-filled ticker and period scope.
   * @param targetField - The target field to map
   * @param customConcept - The custom XBRL concept to use
   * @param context - The earnings context (ticker, frequency, periods)
   * @param options - Optional configuration
   */
  createMappingFromEarnings: (
    targetField: TargetField,
    customConcept: CustomConcept,
    context: EarningsMappingContext,
    options?: EarningsMappingOptions
  ) => Promise<CustomXbrlConceptMapping>;
  /**
   * Create a ticker-specific mapping that applies to all periods for this ticker.
   */
  createTickerSpecificMapping: (
    targetField: TargetField,
    customConcept: CustomConcept,
    context: EarningsMappingContext,
    notes?: string
  ) => Promise<CustomXbrlConceptMapping>;
  /**
   * Create a global mapping that applies to all tickers and periods.
   */
  createGlobalMapping: (
    targetField: TargetField,
    customConcept: CustomConcept,
    notes?: string
  ) => Promise<CustomXbrlConceptMapping>;
}

/**
 * Options for creating an earnings mapping.
 */
export interface EarningsMappingOptions {
  /** Whether to make this a global mapping (default: false, uses ticker) */
  global?: boolean;
  /** Optional notes about the mapping */
  notes?: string;
  /** Optional period start date (ISO format) */
  periodStart?: string;
  /** Optional period end date (ISO format) */
  periodEnd?: string;
}

/**
 * Hook for managing custom XBRL concept mappings in the context of earnings data.
 * Provides convenience functions for creating mappings with earnings-specific context.
 */
export function useEarningsMappings(): UseEarningsMappingsResult {
  const baseHook = useMappings();

  /**
   * Create a mapping from earnings context with pre-filled ticker and optional period scope.
   */
  const createMappingFromEarnings = useCallback(
    async (
      targetField: TargetField,
      customConcept: CustomConcept,
      context: EarningsMappingContext,
      options?: EarningsMappingOptions
    ): Promise<CustomXbrlConceptMapping> => {
      const scope: MappingScope = options?.global
        ? {}
        : {
            ticker: context.symbol,
            periodStart: options?.periodStart,
            periodEnd: options?.periodEnd,
          };

      const mapping = createMapping(targetField, customConcept, scope, options?.notes);

      await baseHook.addMapping(mapping);
      return mapping;
    },
    [baseHook]
  );

  /**
   * Create a ticker-specific mapping that applies to all periods for this ticker.
   */
  const createTickerSpecificMapping = useCallback(
    async (
      targetField: TargetField,
      customConcept: CustomConcept,
      context: EarningsMappingContext,
      notes?: string
    ): Promise<CustomXbrlConceptMapping> => {
      return createMappingFromEarnings(
        targetField,
        customConcept,
        context,
        {
          global: false,
          notes,
        }
      );
    },
    [createMappingFromEarnings]
  );

  /**
   * Create a global mapping that applies to all tickers and periods.
   */
  const createGlobalMapping = useCallback(
    async (
      targetField: TargetField,
      customConcept: CustomConcept,
      notes?: string
    ): Promise<CustomXbrlConceptMapping> => {
      const mapping = createMapping(
        targetField,
        customConcept,
        {}, // Empty scope = global
        notes
      );

      await baseHook.addMapping(mapping);
      return mapping;
    },
    [baseHook]
  );

  return {
    ...baseHook,
    createMappingFromEarnings,
    createTickerSpecificMapping,
    createGlobalMapping,
  };
}
