import { Injectable, inject } from '@angular/core';
import type { SignalServerCredential } from '../../domain/models/signal-server-credential.model';
import { AuthTokenStoreService } from './auth-token-store.service';

const STORAGE_KEY = 'metoyou.signalServerCredentials';

@Injectable({ providedIn: 'root' })
export class SignalServerCredentialStoreService {
  private readonly authTokenStore: AuthTokenStoreService;

  constructor(authTokenStore: AuthTokenStoreService = inject(AuthTokenStoreService)) {
    this.authTokenStore = authTokenStore;
  }

  upsertCredential(credential: SignalServerCredential): void {
    const normalizedUrl = this.normalizeServerUrl(credential.serverUrl);
    const store = this.readStore();

    store[normalizedUrl] = {
      ...credential,
      serverUrl: normalizedUrl
    };

    this.writeStore(store);
    this.authTokenStore.setToken(normalizedUrl, credential.token, credential.expiresAt);
  }

  getCredential(serverUrl: string): SignalServerCredential | null {
    const normalizedUrl = this.normalizeServerUrl(serverUrl);
    const entry = this.readStore()[normalizedUrl];

    if (!entry) {
      return null;
    }

    if (entry.expiresAt <= Date.now()) {
      this.clearCredential(serverUrl);
      return null;
    }

    return entry;
  }

  hasValidCredential(serverUrl: string): boolean {
    return this.getCredential(serverUrl) !== null;
  }

  clearCredential(serverUrl: string): void {
    const normalizedUrl = this.normalizeServerUrl(serverUrl);
    const store = this.readStore();
    const nextStore = Object.fromEntries(
      Object.entries(store).filter(([key]) => key !== normalizedUrl)
    ) as Record<string, SignalServerCredential>;

    this.writeStore(nextStore);
    this.authTokenStore.clearToken(normalizedUrl);
  }

  listValidCredentials(): SignalServerCredential[] {
    const now = Date.now();

    return Object.values(this.readStore()).filter((entry) => entry.expiresAt > now);
  }

  private readStore(): Record<string, SignalServerCredential> {
    try {
      const raw = localStorage.getItem(STORAGE_KEY);

      if (!raw) {
        return {};
      }

      const parsed = JSON.parse(raw) as Record<string, SignalServerCredential>;

      return parsed && typeof parsed === 'object' ? parsed : {};
    } catch {
      return {};
    }
  }

  private writeStore(store: Record<string, SignalServerCredential>): void {
    localStorage.setItem(STORAGE_KEY, JSON.stringify(store));
  }

  private normalizeServerUrl(serverUrl: string): string {
    return serverUrl.trim().replace(/\/+$/, '');
  }
}
