import { UniqueID } from "@/core/common/domain";
import { Result } from "@repo/rdx-utils";
import { TabContext } from "../entities";
import { ITabContextRepository } from "../repositories";
import { ITabContextService } from "./tab-context-service.interface";

export class TabContextService implements ITabContextService {
  constructor(private readonly tabContextRepo: ITabContextRepository) {}

  /**
   * Obtiene el contexto de una pestaña por su ID
   */
  async getContextByTabId(tabId: UniqueID, transaction?: any): Promise<Result<TabContext, Error>> {
    // Verificar si la pestaña existe
    const tabContextOrError = await this.tabContextRepo.getContextByTabId(tabId, transaction);
    if (tabContextOrError.isSuccess && !tabContextOrError.data) {
      return Result.fail(new Error("Invalid or expired Tab ID"));
    }

    if (tabContextOrError.isFailure) {
      return Result.fail(tabContextOrError.error);
    }

    return Result.ok(tabContextOrError.data);
  }

  /**
   * Registra un nuevo contexto de pestaña para un usuario
   */
  async createContext(
    params: {
      tabId: UniqueID;
      userId: UniqueID;
    },
    transaction?: any
  ): Promise<Result<TabContext, Error>> {
    const { tabId, userId } = params;

    if (!userId || !tabId) {
      return Result.fail(new Error("User ID and Tab ID are required"));
    }

    const contextOrError = TabContext.create(
      {
        userId,
        tabId,
      },
      UniqueID.generateNewID().data
    );

    if (contextOrError.isFailure) {
      return Result.fail(contextOrError.error);
    }

    await this.tabContextRepo.registerContextByTabId(contextOrError.data, transaction);

    return Result.ok(contextOrError.data);
  }

  /**
   * Elimina un contexto de pestaña por su ID
   */
  async removeContext(
    params: { tabId: UniqueID; userId: UniqueID },
    transaction?: any
  ): Promise<Result<void, Error>> {
    const { tabId, userId } = params;

    if (!userId || !tabId) {
      return Result.fail(new Error("User ID and Tab ID are required"));
    }

    const contextOrError = TabContext.create(
      {
        userId,
        tabId,
      },
      UniqueID.generateNewID().data
    );

    if (contextOrError.isFailure) {
      return Result.fail(contextOrError.error);
    }

    return await this.tabContextRepo.unregisterContextByTabId(contextOrError.data, transaction);
  }
}
