/**
 * get-user-status.use-case.ts
 * Devuelve la "visión de túnel" del usuario logueado:
 *   - SOLO la ruta asignada a su domicilio
 *   - SOLO sus propias notificaciones
 * No expone rutas ajenas ni telemetría completa.
 */

import { CustomError } from "../../errors/custom.error.js";
import type { EtaResult } from "../notifications/calculate-eta.use-case.js";
import type { RouteStateRepository } from "../../repositories/route-state.repository.js";
import type {
  InboxNotification,
  NotificationInboxRepository,
} from "../../repositories/notification-inbox.repository.js";
import { users } from "../../../data/mocks/users.mock.js";
import { colonias } from "../../../data/mocks/colonias.mock.js";

export interface UserStatusResponse {
  user: { id: number; name: string; colonia: string };
  route: {
    routeId: string;
    currentPositionId: number;
    status: string;
    updatedAt: string;
    horarioEstimado: string | null;
  };
  eta: EtaResult | null;
  notifications: InboxNotification[];
}

export class GetUserStatusUseCase {
  constructor(
    private readonly routeState: RouteStateRepository,
    private readonly inbox: NotificationInboxRepository,
  ) {}

  async execute(userId: number): Promise<UserStatusResponse> {
    const user = users.find((u) => u.id === userId);
    if (!user) {
      throw CustomError.notFound("User not registered in service mock");
    }

    const state = await this.routeState.get(user.routeId);
    const notifications = await this.inbox.getForUser(userId);
    const colonia = colonias.find((c) => c.colonia === user.colonia);

    return {
      user: { id: user.id, name: user.name, colonia: user.colonia },
      route: {
        routeId: user.routeId,
        currentPositionId: state?.currentPositionId ?? 0,
        status: state?.status ?? "ESPERA",
        updatedAt: state?.updatedAt ?? new Date().toISOString(),
        horarioEstimado: colonia?.horarioEstimado ?? null,
      },
      eta: state?.eta ?? null,
      notifications,
    };
  }
}
