/**
 * @ai-summary Donations HTTP controller
 * @ai-context Handles donation creation and history endpoints
 */

import { FastifyRequest, FastifyReply } from 'fastify';
import { DonationsService } from '../domain/donations.service';
import { SubscriptionsRepository } from '../data/subscriptions.repository';
import { StripeClient } from '../external/stripe/stripe.client';
import { pool } from '../../../core/config/database';
import { logger } from '../../../core/logging/logger';

interface CreateDonationBody {
  amount: number;
}

export class DonationsController {
  private service: DonationsService;

  constructor() {
    const repository = new SubscriptionsRepository(pool);
    const stripeClient = new StripeClient();
    this.service = new DonationsService(repository, stripeClient, pool);
  }

  /**
   * POST /api/donations - Create donation payment intent
   */
  async createDonation(request: FastifyRequest, reply: FastifyReply) {
    try {
      const userId = (request as any).user.sub;
      const { amount } = request.body as CreateDonationBody;

      logger.info('Creating donation', { userId, amount });

      // Validate amount
      if (!amount || amount <= 0) {
        return reply.code(400).send({ error: 'Invalid amount' });
      }

      // Convert dollars to cents
      const amountCents = Math.round(amount * 100);

      // Create donation
      const result = await this.service.createDonation(userId, amountCents);

      return reply.code(201).send(result);
    } catch (error: any) {
      logger.error('Failed to create donation', {
        error: error.message,
      });

      if (error.message.includes('must be at least')) {
        return reply.code(400).send({ error: error.message });
      }

      return reply.code(500).send({ error: 'Failed to create donation' });
    }
  }

  /**
   * GET /api/donations - Get user's donation history
   */
  async getDonations(request: FastifyRequest, reply: FastifyReply) {
    try {
      const userId = (request as any).user.sub;

      logger.info('Getting donations', { userId });

      const donations = await this.service.getUserDonations(userId);

      return reply.code(200).send(donations);
    } catch (error: any) {
      logger.error('Failed to get donations', {
        error: error.message,
      });

      return reply.code(500).send({ error: 'Failed to get donations' });
    }
  }
}
