import type { Logger, UseCaseOutputPort } from '@core/shared/application';
import { Result } from '@core/shared/application/Result';
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
import type { ISocialGraphRepository } from '../../domain/repositories/ISocialGraphRepository';
import type { SocialFriendSummary, SocialUserSummary } from '../types/SocialUser';

export interface GetCurrentUserSocialParams {
  driverId: string;
}

export type GetCurrentUserSocialInput = GetCurrentUserSocialParams;

export interface GetCurrentUserSocialResult {
  currentUser: SocialUserSummary;
  friends: SocialFriendSummary[];
}

export type GetCurrentUserSocialErrorCode = 'REPOSITORY_ERROR';

export type GetCurrentUserSocialApplicationError = ApplicationErrorCode<
  GetCurrentUserSocialErrorCode,
  { message: string }
>;

/**
 * Application-level use case to retrieve the current user's social context.
 *
 * Keeps orchestration in the social bounded context while delegating
 * data access to domain repositories and presenting via an output port.
 */
export class GetCurrentUserSocialUseCase {
  constructor(
    private readonly socialGraphRepository: ISocialGraphRepository,
    private readonly logger: Logger,
    private readonly output: UseCaseOutputPort<GetCurrentUserSocialResult>,
  ) {}

  async execute(
    input: GetCurrentUserSocialInput,
  ): Promise<Result<void, GetCurrentUserSocialApplicationError>> {
    this.logger.debug('GetCurrentUserSocialUseCase.execute: Starting execution', { input });

    try {
      const { driverId } = input;

      this.logger.debug(
        'GetCurrentUserSocialUseCase.execute: Fetching friends for driverId',
        { driverId },
      );
      const friendsDomain = await this.socialGraphRepository.getFriends(driverId);
      this.logger.debug(
        'GetCurrentUserSocialUseCase.execute: Successfully fetched friends from social graph repository',
        { friendsCount: friendsDomain.length },
      );
      if (friendsDomain.length === 0) {
        this.logger.warn(
          `GetCurrentUserSocialUseCase.execute: No friends found for driverId: ${driverId}`,
        );
      }

      // The social graph context currently only knows about relationships.
      // Profile fields for the current user are expected to be enriched by identity/profile contexts.
      const friends: SocialFriendSummary[] = friendsDomain.map((friend) => ({
        driverId: friend.id,
        displayName: friend.name.toString(),
        avatarUrl: '',
        countryCode: '',
        isOnline: false,
        lastSeen: new Date(),
      }));

      const currentUser: SocialUserSummary = {
        driverId,
        displayName: '',
        avatarUrl: '',
        countryCode: '',
      };

      const result: GetCurrentUserSocialResult = {
        currentUser,
        friends,
      };

      this.output.present(result);
      this.logger.info(
        'GetCurrentUserSocialUseCase.execute: Successfully presented current user social data',
      );

      return Result.ok(undefined);
    } catch (error) {
      const err = error instanceof Error ? error : new Error(String(error));

      this.logger.error(
        'GetCurrentUserSocialUseCase.execute: Error during execution',
        err,
        { input },
      );

      return Result.err({
        code: 'REPOSITORY_ERROR',
        details: {
          message: err.message,
        },
      } as GetCurrentUserSocialApplicationError);
    }
  }
}