import {
  Injectable,
  Inject,
  NotFoundException,
  Redirect,
} from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import Stripe from 'stripe';
import { Enrollment } from '../enrollments/enrollment.entity';
import { Course } from '../course/course.entity';
import { ConfigService } from '@nestjs/config';
import { MailService } from '../mail/mail.service';

@Injectable()
export class BillingService {
  constructor(
    @Inject('STRIPE') private stripe: Stripe,
    private config: ConfigService,
    @InjectRepository(Enrollment) private enrollRepo: Repository<Enrollment>,
    private mailService: MailService,
  ) { }

  // One-time payment Checkout flow
  async createOneTimeCheckout(
    id: number,
    course: Course,
    opts?: {
      allowPromotionCodes?: boolean;
      automaticTax?: boolean;
    },
  ) {
    const currency = this.config.get<string>('CURRENCY')!;
    const amount = Number(course.discountPrice ?? course.price) * 100;

    const session = await this.stripe.checkout.sessions.create({
      mode: 'payment',
      allow_promotion_codes: opts?.allowPromotionCodes ?? true,
      automatic_tax: { enabled: !!opts?.automaticTax }, // Stripe tax if you enable it in dashboard
      payment_method_types: ['card', 'link'], // add more as Stripe enables for your account
      line_items: [
        {
          price_data: {
            currency,
            product_data: {
              name: course.title,
              description: course.description.slice(0, 200),
            },
            unit_amount: Math.round(amount),
          },
          quantity: 1,
        },
      ],
      success_url: `https://trytalento.glmaagencyprojects.com/billing/success?session_id={CHECKOUT_SESSION_ID}`,
      cancel_url: `https://trytalento.glmaagencyprojects.com/billing/cancel`,
      metadata: { id: String(id), courseId: String(course.id) },
    });

    // Upsert pending enrollment (idempotent)
    let enroll = await this.enrollRepo.findOne({
      where: { user: { id: id }, course: { id: course.id } },
    });
    if (!enroll) {
      enroll = this.enrollRepo.create({
        user: { id: id } as any,
        course: { id: course.id } as any,
        status: 'pending',
      });
    } else {
      enroll.status = 'pending';
    }
    await this.enrollRepo.save(enroll);

    return { url: session.url };
  }

  async activateEnrollmentFromCheckout(session: Stripe.Checkout.Session) {
    const id = Number(session.metadata?.id);
    const courseId = Number(session.metadata?.courseId);
    if (!id || !courseId) return;

    const enroll = await this.enrollRepo.findOne({
      where: { user: { id: id }, course: { id: courseId } },
    });
    if (!enroll) return;
    enroll.status = 'active';
    await this.enrollRepo.save(enroll);
  }

  /**
   * Confirm a checkout session and activate the enrollment
   * @param sessionId Stripe Checkout session ID
   */
  async confirmCheckoutSession(sessionId: string) {
    if (!sessionId) throw new NotFoundException('Session ID is required');

    const session = await this.stripe.checkout.sessions.retrieve(sessionId);
    if (!session) throw new NotFoundException('Checkout session not found');

    const paymentStatus = session.payment_status;
    const userId = Number(session.metadata?.id);
    const courseId = Number(session.metadata?.courseId);

    if (paymentStatus === 'paid' && userId && courseId) {
      const enroll = await this.enrollRepo.findOne({
        where: { user: { id: userId }, course: { id: courseId } },
      });
      if (!enroll) throw new NotFoundException('Enrollment not found');

      enroll.status = 'active';
      await this.enrollRepo.save(enroll);

      // Send confirmation email
      if (enroll.user && enroll.course) {
        this.mailService.sendEnrollmentConfirmation(
          enroll.user.email,
          '', // No username in User entity, could use email or add name later
          enroll.course.title,
          enroll.course.id,
        );
      }

      return enroll;
    }

    return null;
  }
}
