/**
 * Entity Resolution Utilities
 * 
 * Functions for resolving entity names and display information
 * from cached entity data used in moderation workflows.
 */

/**
 * Entity cache structure (matching useEntityCache hook)
 */
interface EntityCache {
  rides: Map<string, { id: string; name: string; park_id?: string }>;
  parks: Map<string, { id: string; name: string }>;
  companies: Map<string, { id: string; name: string }>;
}

/**
 * Generic submission content type
 */
interface GenericSubmissionContent {
  name?: string;
  entity_id?: string;
  entity_name?: string;
  park_id?: string;
  ride_id?: string;
  company_id?: string;
  manufacturer_id?: string;
  designer_id?: string;
  operator_id?: string;
  property_owner_id?: string;
  [key: string]: unknown;
}

/**
 * Result of entity name resolution
 */
export interface ResolvedEntityNames {
  entityName: string;
  parkName?: string;
}

/**
 * Resolve entity name and related park name from submission content
 * 
 * This function determines what entity is being modified based on the
 * submission type and content, then looks up cached entity data to
 * resolve display names.
 * 
 * @param submissionType - Type of submission (e.g., 'ride', 'park', 'manufacturer')
 * @param content - Submission content containing entity IDs
 * @param entityCache - Cache of entity data
 * @returns Resolved entity and park names
 * 
 * @example
 * ```tsx
 * const { entityName, parkName } = resolveEntityName(
 *   'ride',
 *   { entity_id: 'ride-123' },
 *   entityCacheRef.current
 * );
 * // Returns: { entityName: "Steel Vengeance", parkName: "Cedar Point" }
 * ```
 */
export function resolveEntityName(
  submissionType: string,
  content: GenericSubmissionContent | null | undefined,
  entityCache: EntityCache
): ResolvedEntityNames {
  let entityName = content?.name || 'Unknown';
  let parkName: string | undefined;

  // Handle ride submissions - look up ride name and park
  if (submissionType === 'ride' && content?.entity_id) {
    const ride = entityCache.rides.get(content.entity_id);
    if (ride) {
      entityName = ride.name;
      if (ride.park_id) {
        const park = entityCache.parks.get(ride.park_id);
        if (park) parkName = park.name;
      }
    }
  }
  // Handle park submissions
  else if (submissionType === 'park' && content?.entity_id) {
    const park = entityCache.parks.get(content.entity_id);
    if (park) entityName = park.name;
  }
  // Handle company submissions (manufacturer, operator, designer, property_owner)
  else if (
    ['manufacturer', 'operator', 'designer', 'property_owner'].includes(submissionType) &&
    content?.entity_id
  ) {
    const company = entityCache.companies.get(content.entity_id);
    if (company) entityName = company.name;
  }
  // Handle content with ride_id reference
  else if (content?.ride_id) {
    const ride = entityCache.rides.get(content.ride_id);
    if (ride) {
      entityName = ride.name;
      if (ride.park_id) {
        const park = entityCache.parks.get(ride.park_id);
        if (park) parkName = park.name;
      }
    }
  }
  // Handle content with park_id reference
  else if (content?.park_id) {
    const park = entityCache.parks.get(content.park_id);
    if (park) parkName = park.name;
  }

  return { entityName, parkName };
}

/**
 * Get a display-ready entity identifier string
 * 
 * Combines entity name and park name (if available) into a single
 * human-readable string for display in the moderation interface.
 * 
 * @param entityName - Primary entity name
 * @param parkName - Optional related park name
 * @returns Formatted display string
 * 
 * @example
 * ```tsx
 * getEntityDisplayName("Steel Vengeance", "Cedar Point")
 * // Returns: "Steel Vengeance at Cedar Point"
 * 
 * getEntityDisplayName("Cedar Point")
 * // Returns: "Cedar Point"
 * ```
 */
export function getEntityDisplayName(
  entityName: string,
  parkName?: string
): string {
  if (parkName) {
    return `${entityName} at ${parkName}`;
  }
  return entityName;
}

/**
 * Extract all entity IDs from a list of submissions
 * 
 * Scans through submission content to find all referenced entity IDs,
 * grouped by entity type (rides, parks, companies).
 * 
 * @param submissions - Array of submission objects
 * @returns Object containing Sets of IDs for each entity type
 */
export function extractEntityIds(submissions: Array<{ content: unknown; submission_type: string }>): {
  rideIds: Set<string>;
  parkIds: Set<string>;
  companyIds: Set<string>;
} {
  const rideIds = new Set<string>();
  const parkIds = new Set<string>();
  const companyIds = new Set<string>();

  submissions.forEach(submission => {
    const content = submission.content as GenericSubmissionContent | null | undefined;
    if (content && typeof content === 'object') {
      // Direct entity references
      if (content.ride_id) rideIds.add(content.ride_id);
      if (content.park_id) parkIds.add(content.park_id);
      if (content.company_id) companyIds.add(content.company_id);

      // Entity ID based on submission type
      if (content.entity_id) {
        if (submission.submission_type === 'ride') {
          rideIds.add(content.entity_id);
        } else if (submission.submission_type === 'park') {
          parkIds.add(content.entity_id);
        } else if (
          ['manufacturer', 'operator', 'designer', 'property_owner'].includes(
            submission.submission_type
          )
        ) {
          companyIds.add(content.entity_id);
        }
      }

      // Company role references
      if (content.manufacturer_id) companyIds.add(content.manufacturer_id);
      if (content.designer_id) companyIds.add(content.designer_id);
      if (content.operator_id) companyIds.add(content.operator_id);
      if (content.property_owner_id) companyIds.add(content.property_owner_id);
    }
  });

  return { rideIds, parkIds, companyIds };
}

/**
 * Determine submission type display label
 * 
 * Converts internal submission type identifiers to human-readable labels.
 * 
 * @param submissionType - Internal submission type
 * @returns Human-readable label
 */
export function getSubmissionTypeLabel(submissionType: string): string {
  const labels: Record<string, string> = {
    park: 'Park',
    ride: 'Ride',
    manufacturer: 'Manufacturer',
    operator: 'Operator',
    designer: 'Designer',
    property_owner: 'Property Owner',
    ride_model: 'Ride Model',
    photo: 'Photo',
    photo_delete: 'Photo Deletion',
    milestone: 'Timeline Event',
    timeline_event: 'Timeline Event',
    review: 'Review',
  };

  return labels[submissionType] || submissionType;
}
