import {inject, Injectable, Signal, signal, WritableSignal} from '@angular/core';
import {IndexedDB} from './storage/indexed-db';
import {Keyring} from './storage/keyring';
import {KeyValue} from './storage/key-value';
import {SessionManager} from '@chatenium/chatenium-sdk/services/sessionManager';
import {Session} from '@chatenium/chatenium-sdk/domain/sessionManager.schema';
import {ChatService} from '@chatenium/chatenium-sdk/services/chatService';
import {Chat} from '@chatenium/chatenium-sdk/domain/chatService.schema';
import {DMService} from '@chatenium/chatenium-sdk/services/dmService';
import {Message} from '@chatenium/chatenium-sdk/domain/dmService.schema';
import {MessageBoxViewModel} from './chat/elements/message-box/message-box-viewmodel';
import {NetworkService} from '@chatenium/chatenium-sdk/services/networkService';
import {Network, NetworkCategory, NetworkChannel} from '@chatenium/chatenium-sdk/domain/networkService.schema';
import {TextChannelServiceService} from '@chatenium/chatenium-sdk/services/textChannelService';
import {Message as NetworkMessage} from '@chatenium/chatenium-sdk/domain/textChannelService.schema';
import {PictureService} from '@chatenium/chatenium-sdk/services/pictureService';
import {Album} from '@chatenium/chatenium-sdk/domain/pictureService.schema';
import {PublicUserData} from '@chatenium/chatenium-sdk/domain/common.schema';

@Injectable({
  providedIn: 'root',
})
export class ServiceManager {
  database = inject(IndexedDB)
  keyring = inject(Keyring)
  keyValue = inject(KeyValue)

  sessionManager = new SessionManager(this.database.getApi(), this.keyring.getApi(), this.keyValue.getApi())
  currentSession = signal<Session | null>(null)

  chatService: ChatService | null = null // Initialized in picture-list.ts
  chatsStatus = signal<LoadStatus>(LoadStatus.loading)
  chats = signal<Chat[]>([])

  networkService: NetworkService | null = null // Initialized in network-list.ts
  networksStatus = signal<LoadStatus>(LoadStatus.loading)
  networks = signal<Network[]>([])
  // Services for individual networks
  networkServices = signal<Record<string, NetworkStorage>>({})

  dmServices = signal<Record<string, DmStorage>>({})
  pictureServices = signal<Record<string, PictureStorage>>({})
}

export enum LoadStatus {
  loading = 0,
  loaded = 1,
  error = 2,
  updating = 3,
}

export interface DmStorage {
  service: DMService
  messages: WritableSignal<Message[]>
  chatData: WritableSignal<Chat>
  messageBox: MessageBoxViewModel
  wsListener: (action: string, message: string) => void
}

export interface PictureStorage {
  service: PictureService
  albums: WritableSignal<Album[]>
  uploaderData: WritableSignal<PublicUserData>
}

export interface NetworkStorage {
  service: NetworkService
  networkData: WritableSignal<Network>
  wsListener: (action: string, message: string) => void
  textChannels: WritableSignal<Record<string, TextChannelStorage>>
}

export interface TextChannelStorage {
  service: TextChannelServiceService
  messages: WritableSignal<NetworkMessage[]>
  channelData: WritableSignal<NetworkChannel>
  categoryData: WritableSignal<NetworkCategory>
  messageBox: MessageBoxViewModel
  wsListener: (action: string, message: string) => void
}
