import {
  Injectable,
  computed,
  inject
} from '@angular/core';

import { resolveMobileAdapter } from '../logic/mobile-capacitor-adapter.rules';
import { ensureMobileCameraCapturePermissions, ensureMobileVoiceCapturePermissions } from '../logic/ensure-mobile-capture-permissions';
import type { MobileMediaAdapter } from '../contracts/mobile.contracts';
import { WebMobileMediaAdapter } from '../adapters/web/web-mobile-media.adapter';
import { MobilePlatformService } from './mobile-platform.service';

/** Facade for mobile media affordances: attachments, speakerphone, background audio, capture limits. */
@Injectable({ providedIn: 'root' })
export class MobileMediaService {
  readonly isScreenShareSupported = computed(() => this.adapter.isScreenShareSupported());
  readonly isPictureInPictureSupported = computed(() => this.adapter.isPictureInPictureSupported());

  private readonly mobilePlatform = inject(MobilePlatformService);
  private adapter: MobileMediaAdapter = new WebMobileMediaAdapter();
  private adapterReady: Promise<MobileMediaAdapter> | null = null;

  pickAttachments(): Promise<File[]> {
    return this.ensureAdapter().then((adapter) => adapter.pickAttachments());
  }

  setSpeakerphoneEnabled(enabled: boolean): Promise<void> {
    return this.ensureAdapter().then((adapter) => adapter.setSpeakerphoneEnabled(enabled));
  }

  startBackgroundAudioSession(): Promise<void> {
    return this.ensureAdapter().then((adapter) => adapter.startBackgroundAudioSession());
  }

  stopBackgroundAudioSession(): Promise<void> {
    return this.ensureAdapter().then((adapter) => adapter.stopBackgroundAudioSession());
  }

  ensureVoiceCapturePermissions(): Promise<boolean> {
    return ensureMobileVoiceCapturePermissions();
  }

  ensureCameraCapturePermissions(): Promise<boolean> {
    return ensureMobileCameraCapturePermissions();
  }

  private ensureAdapter(): Promise<MobileMediaAdapter> {
    if (!this.adapterReady) {
      this.adapterReady = resolveMobileAdapter(
        this.mobilePlatform.runtime(),
        this.adapter,
        async () => {
          const { CapacitorMobileMediaAdapter } = await import('../adapters/capacitor/capacitor-mobile-media.adapter');

          return new CapacitorMobileMediaAdapter();
        }
      ).then((adapter) => {
        this.adapter = adapter;
        return adapter;
      });
    }

    return this.adapterReady;
  }
}
