import { injectable } from 'inversify';
import { PolicyApiClient, type FeatureState, type PolicySnapshotDto } from '@/lib/api/policy/PolicyApiClient';
import { Result } from '@/lib/contracts/Result';
import { DomainError, Service } from '@/lib/contracts/services/Service';
import { getWebsiteApiBaseUrl } from '@/lib/config/apiBaseUrl';
import { ConsoleLogger } from '@/lib/infrastructure/logging/ConsoleLogger';
import { EnhancedErrorReporter } from '@/lib/infrastructure/EnhancedErrorReporter';

export interface CapabilityEvaluationResult {
  isLoading: boolean;
  isError: boolean;
  capabilityState: FeatureState | null;
  shouldShowChildren: boolean;
  shouldShowComingSoon: boolean;
}

@injectable()
export class PolicyService implements Service {
  private readonly apiClient: PolicyApiClient;

  constructor() {
    const baseUrl = getWebsiteApiBaseUrl();
    const logger = new ConsoleLogger();
    const errorReporter = new EnhancedErrorReporter(logger);
    this.apiClient = new PolicyApiClient(baseUrl, errorReporter, logger);
  }

  async getSnapshot(): Promise<Result<PolicySnapshotDto, DomainError>> {
    try {
      const data = await this.apiClient.getSnapshot();
      return Result.ok(data);
    } catch (error: any) {
      return Result.err({ type: 'serverError', message: error.message || 'Failed to get policy snapshot' });
    }
  }

  getCapabilityState(snapshot: PolicySnapshotDto, capabilityKey: string): FeatureState {
    return snapshot.capabilities[capabilityKey] ?? 'hidden';
  }

  isCapabilityEnabled(snapshot: PolicySnapshotDto, capabilityKey: string): boolean {
    return this.getCapabilityState(snapshot, capabilityKey) === 'enabled';
  }

  /**
   * Evaluate capability state and determine what should be rendered
   * Centralizes the logic for capability-based UI rendering
   */
  evaluateCapability(
    snapshot: PolicySnapshotDto | null,
    capabilityKey: string,
    isLoading: boolean,
    isError: boolean
  ): CapabilityEvaluationResult {
    if (isLoading || isError || !snapshot) {
      return {
        isLoading,
        isError,
        capabilityState: null,
        shouldShowChildren: false,
        shouldShowComingSoon: false,
      };
    }

    const capabilityState = this.getCapabilityState(snapshot, capabilityKey);
    
    return {
      isLoading,
      isError,
      capabilityState,
      shouldShowChildren: capabilityState === 'enabled',
      shouldShowComingSoon: capabilityState === 'coming_soon',
    };
  }

  /**
   * Get the appropriate content based on capability state
   * Handles fallback and coming soon logic
   */
  getCapabilityContent(
    snapshot: PolicySnapshotDto | null,
    capabilityKey: string,
    isLoading: boolean,
    isError: boolean,
    children: React.ReactNode,
    fallback: React.ReactNode = null,
    comingSoon: React.ReactNode = null
  ): React.ReactNode {
    const evaluation = this.evaluateCapability(snapshot, capabilityKey, isLoading, isError);

    if (evaluation.shouldShowChildren) {
      return children;
    }

    if (evaluation.shouldShowComingSoon) {
      return comingSoon ?? fallback;
    }

    return fallback;
  }
}
