import { Logger } from "winston";
import { SetIdentityPayload } from "@mcpx/webapp-protocol/messages";

// Identity is a discriminated union: Personal or Enterprise
// Enterprise entity type is derived from protocol's SetIdentityPayload

export interface PersonalIdentity {
  mode: "personal";
}

export interface EnterpriseIdentity {
  mode: "enterprise";
  entity: SetIdentityPayload;
}

export type Identity = PersonalIdentity | EnterpriseIdentity;

export interface IdentityServiceI {
  getIdentity(): Identity;
  setIdentity(payload: SetIdentityPayload): void;
  isSpace(): boolean;
  isAdmin(): boolean;
  getDisplayName(): string | undefined;
}

// Default enterprise identity before hub sends info: user with member role (most restrictive)
const DEFAULT_ENTERPRISE_ENTITY: SetIdentityPayload = {
  entityType: "user",
  role: "member",
};

export class IdentityService implements IdentityServiceI {
  private identity: Identity;
  private logger: Logger;
  constructor(logger: Logger, config: { isEnterprise: boolean }) {
    this.logger = logger.child({ component: "IdentityService" });

    this.identity = config.isEnterprise
      ? { mode: "enterprise", entity: DEFAULT_ENTERPRISE_ENTITY }
      : { mode: "personal" };

    this.logger.info("Identity service initialized", {
      mode: this.identity.mode,
    });
  }

  getIdentity(): Identity {
    return this.identity;
  }

  getDisplayName(): string | undefined {
    if (
      this.identity.mode === "enterprise" &&
      this.identity.entity.entityType === "user"
    ) {
      return this.identity.entity.displayName;
    }
    return undefined;
  }

  setIdentity(payload: SetIdentityPayload): void {
    if (this.identity.mode === "personal") {
      this.logger.warn(
        "Ignoring set-identity in personal mode - identity is fixed",
      );
      return;
    }

    this.identity = {
      mode: "enterprise",
      entity: payload,
    };

    this.logger.info("Identity updated from hub", {
      entityType: payload.entityType,
      role: payload.entityType === "user" ? payload.role : undefined,
    });
  }

  isSpace(): boolean {
    return isSpace(this.identity);
  }

  isAdmin(): boolean {
    return isAdmin(this.identity);
  }
}

export function isAdmin(identity: Identity): boolean {
  if (identity.mode === "personal") {
    return false;
  }
  if (identity.entity.entityType === "space") {
    return false;
  }
  return identity.entity.role === "admin";
}

export function isSpace(identity: Identity): boolean {
  if (identity.mode === "personal") {
    return false;
  }
  return identity.entity.entityType === "space";
}
