import { Injectable, Inject } from '@nestjs/common';
import { GetEntitySponsorshipPricingResultDTO } from './dtos/GetEntitySponsorshipPricingResultDTO';
import { GetSponsorsOutputDTO } from './dtos/GetSponsorsOutputDTO';
import { CreateSponsorInputDTO } from './dtos/CreateSponsorInputDTO';
import { CreateSponsorOutputDTO } from './dtos/CreateSponsorOutputDTO';
import { GetSponsorDashboardQueryParamsDTO } from './dtos/GetSponsorDashboardQueryParamsDTO';
import { SponsorDashboardDTO } from './dtos/SponsorDashboardDTO';
import { GetSponsorSponsorshipsQueryParamsDTO } from './dtos/GetSponsorSponsorshipsQueryParamsDTO';
import { SponsorSponsorshipsDTO } from './dtos/SponsorSponsorshipsDTO';
import { SponsorDTO } from './dtos/SponsorDTO';
import { SponsorDashboardMetricsDTO } from './dtos/SponsorDashboardMetricsDTO';
import { SponsoredLeagueDTO } from './dtos/SponsoredLeagueDTO';
import { SponsorDashboardInvestmentDTO } from './dtos/SponsorDashboardInvestmentDTO';
import { SponsorshipDetailDTO } from './dtos/SponsorshipDetailDTO';

// Use cases
import { GetSponsorshipPricingUseCase } from '@core/racing/application/use-cases/GetSponsorshipPricingUseCase';
import { GetSponsorsUseCase } from '@core/racing/application/use-cases/GetSponsorsUseCase';
import { CreateSponsorUseCase } from '@core/racing/application/use-cases/CreateSponsorUseCase';
import { GetSponsorDashboardUseCase } from '@core/racing/application/use-cases/GetSponsorDashboardUseCase';
import { GetSponsorSponsorshipsUseCase } from '@core/racing/application/use-cases/GetSponsorSponsorshipsUseCase';

// Presenters
import { GetSponsorshipPricingPresenter } from './presenters/GetSponsorshipPricingPresenter';
import { GetSponsorsPresenter } from './presenters/GetSponsorsPresenter';
import { CreateSponsorPresenter } from './presenters/CreateSponsorPresenter';
import { GetSponsorDashboardPresenter } from './presenters/GetSponsorDashboardPresenter';
import { GetSponsorSponsorshipsPresenter } from './presenters/GetSponsorSponsorshipsPresenter';

// Tokens
import { GET_SPONSORSHIP_PRICING_USE_CASE_TOKEN, GET_SPONSORS_USE_CASE_TOKEN, CREATE_SPONSOR_USE_CASE_TOKEN, GET_SPONSOR_DASHBOARD_USE_CASE_TOKEN, GET_SPONSOR_SPONSORSHIPS_USE_CASE_TOKEN, LOGGER_TOKEN } from './SponsorProviders';
import type { Logger } from '@core/shared/application';

@Injectable()
export class SponsorService {
  constructor(
    @Inject(GET_SPONSORSHIP_PRICING_USE_CASE_TOKEN) private readonly getSponsorshipPricingUseCase: GetSponsorshipPricingUseCase,
    @Inject(GET_SPONSORS_USE_CASE_TOKEN) private readonly getSponsorsUseCase: GetSponsorsUseCase,
    @Inject(CREATE_SPONSOR_USE_CASE_TOKEN) private readonly createSponsorUseCase: CreateSponsorUseCase,
    @Inject(GET_SPONSOR_DASHBOARD_USE_CASE_TOKEN) private readonly getSponsorDashboardUseCase: GetSponsorDashboardUseCase,
    @Inject(GET_SPONSOR_SPONSORSHIPS_USE_CASE_TOKEN) private readonly getSponsorSponsorshipsUseCase: GetSponsorSponsorshipsUseCase,
    @Inject(LOGGER_TOKEN) private readonly logger: Logger,
  ) {}

  async getEntitySponsorshipPricing(): Promise<GetEntitySponsorshipPricingResultDTO> {
    this.logger.debug('[SponsorService] Fetching sponsorship pricing.');

    const presenter = new GetSponsorshipPricingPresenter();
    await this.getSponsorshipPricingUseCase.execute(undefined, presenter);
    return presenter.viewModel;
  }

  async getSponsors(): Promise<GetSponsorsOutputDTO> {
    this.logger.debug('[SponsorService] Fetching sponsors.');

    const presenter = new GetSponsorsPresenter();
    await this.getSponsorsUseCase.execute(undefined, presenter);
    return presenter.viewModel;
  }

  async createSponsor(input: CreateSponsorInputDTO): Promise<CreateSponsorOutputDTO> {
    this.logger.debug('[SponsorService] Creating sponsor.', { input });

    const presenter = new CreateSponsorPresenter();
    await this.createSponsorUseCase.execute(input, presenter);
    return presenter.viewModel;
  }

  async getSponsorDashboard(params: GetSponsorDashboardQueryParamsDTO): Promise<SponsorDashboardDTO | null> {
    this.logger.debug('[SponsorService] Fetching sponsor dashboard.', { params });

    const presenter = new GetSponsorDashboardPresenter();
    await this.getSponsorDashboardUseCase.execute(params, presenter);
    return presenter.viewModel as SponsorDashboardDTO | null;
  }

  async getSponsorSponsorships(params: GetSponsorSponsorshipsQueryParamsDTO): Promise<SponsorSponsorshipsDTO | null> {
    this.logger.debug('[SponsorService] Fetching sponsor sponsorships.', { params });

    const presenter = new GetSponsorSponsorshipsPresenter();
    await this.getSponsorSponsorshipsUseCase.execute(params, presenter);
    return presenter.viewModel as SponsorSponsorshipsDTO | null;
  }
}
