/* eslint-disable @typescript-eslint/member-ordering */
import {
  Injectable,
  computed,
  effect,
  inject,
  signal
} from '@angular/core';

import { VoiceSessionFacade } from '../facades/voice-session.facade';

export type VoiceWorkspaceMode = 'hidden' | 'expanded' | 'minimized';

export interface VoiceWorkspacePosition {
  left: number;
  top: number;
}

const DEFAULT_MINI_WINDOW_POSITION: VoiceWorkspacePosition = {
  left: 24,
  top: 24
};

@Injectable({ providedIn: 'root' })
export class VoiceWorkspaceService {
  private readonly voiceSession = inject(VoiceSessionFacade);

  private readonly _mode = signal<VoiceWorkspaceMode>('hidden');
  private readonly _focusedStreamId = signal<string | null>(null);
  private readonly _connectRemoteShares = signal(false);
  private readonly _miniWindowPosition = signal<VoiceWorkspacePosition>(
    DEFAULT_MINI_WINDOW_POSITION
  );
  private readonly _hasCustomMiniWindowPosition = signal(false);

  readonly mode = computed<VoiceWorkspaceMode>(() => {
    if (!this.voiceSession.voiceSession() || !this.voiceSession.isViewingVoiceServer()) {
      return 'hidden';
    }

    return this._mode();
  });

  readonly isExpanded = computed(() => this.mode() === 'expanded');
  readonly isMinimized = computed(() => this.mode() === 'minimized');
  readonly isVisible = computed(() => this.mode() !== 'hidden');
  readonly focusedStreamId = computed(() => this._focusedStreamId());
  readonly shouldConnectRemoteShares = computed(
    () => this.isVisible() && this._connectRemoteShares()
  );
  readonly miniWindowPosition = computed(() => this._miniWindowPosition());
  readonly hasCustomMiniWindowPosition = computed(() => this._hasCustomMiniWindowPosition());

  constructor() {
    effect(() => {
      if (this.voiceSession.voiceSession()) {
        return;
      }

      this.reset();
    });
  }

  open(
    focusedStreamId: string | null = null,
    options?: { connectRemoteShares?: boolean }
  ): void {
    if (!this.voiceSession.voiceSession()) {
      return;
    }

    if (options && Object.prototype.hasOwnProperty.call(options, 'connectRemoteShares')) {
      this._connectRemoteShares.set(options.connectRemoteShares === true);
    }

    this._focusedStreamId.set(focusedStreamId);
    this._mode.set('expanded');
  }

  focusStream(streamId: string, options?: { connectRemoteShares?: boolean }): void {
    this.open(streamId, options);
  }

  minimize(): void {
    if (!this.voiceSession.voiceSession()) {
      return;
    }

    this._mode.set('minimized');
  }

  restore(): void {
    this.open(this._focusedStreamId());
  }

  close(): void {
    this._mode.set('hidden');
    this._connectRemoteShares.set(false);
  }

  showChat(): void {
    if (this._mode() === 'expanded') {
      this._mode.set('hidden');
      this._connectRemoteShares.set(false);
    }
  }

  clearFocusedStream(): void {
    this._focusedStreamId.set(null);
  }

  setMiniWindowPosition(position: VoiceWorkspacePosition, markCustom = true): void {
    this._miniWindowPosition.set(position);
    this._hasCustomMiniWindowPosition.set(markCustom);
  }

  resetMiniWindowPosition(): void {
    this._miniWindowPosition.set(DEFAULT_MINI_WINDOW_POSITION);
    this._hasCustomMiniWindowPosition.set(false);
  }

  reset(): void {
    this._mode.set('hidden');
    this._focusedStreamId.set(null);
    this._connectRemoteShares.set(false);
    this.resetMiniWindowPosition();
  }
}
