import {
  Controller, Get, Post, Body, Headers, HttpCode, HttpStatus,
} from '@nestjs/common';
import { SubscriptionRepository } from '../../../infrastructure/repositories/subscription.repository';
import { PlanRepository } from '../../../infrastructure/repositories/plan.repository';
import { ChangePlanUseCase } from '../../../application/use-cases/change-plan.use-case';
import { CancelSubscriptionUseCase } from '../../../application/use-cases/cancel-subscription.use-case';
import { CheckTokenQuotaUseCase } from '../../../application/use-cases/check-token-quota.use-case';
import { InvoiceCurrency } from '../../../domain/entities/invoice.entity';

@Controller('api/v1/billing')
export class SubscriptionController {
  constructor(
    private readonly subscriptionRepo: SubscriptionRepository,
    private readonly planRepo: PlanRepository,
    private readonly changePlan: ChangePlanUseCase,
    private readonly cancelSubscription: CancelSubscriptionUseCase,
    private readonly checkQuota: CheckTokenQuotaUseCase,
  ) {}

  @Get('subscription')
  async getSubscription(@Headers('x-tenant-id') tenantId: string) {
    const sub = await this.subscriptionRepo.findByTenantId(tenantId);
    if (!sub) {
      // No subscription yet — return a default free-plan stub so the UI renders gracefully
      const freePlan = await this.planRepo.findByName('free');
      return {
        id: null,
        status: 'none',
        plan: freePlan ? { name: freePlan.name, displayName: freePlan.displayName } : { name: 'free', displayName: 'Free' },
        nextPlan: null,
        currentPeriodStart: null,
        currentPeriodEnd: null,
        trialEndsAt: null,
        cancelAtPeriodEnd: false,
        cancelledAt: null,
      };
    }

    const plan = await this.planRepo.findById(sub.planId);
    const nextPlan = sub.nextPlanId ? await this.planRepo.findById(sub.nextPlanId) : null;

    return {
      id: sub.id,
      status: sub.status,
      plan: plan ? { name: plan.name, displayName: plan.displayName } : null,
      nextPlan: nextPlan ? { name: nextPlan.name, displayName: nextPlan.displayName } : null,
      currentPeriodStart: sub.currentPeriodStart,
      currentPeriodEnd: sub.currentPeriodEnd,
      trialEndsAt: sub.trialEndsAt,
      cancelAtPeriodEnd: sub.cancelAtPeriodEnd,
      cancelledAt: sub.cancelledAt,
    };
  }

  @Post('subscription/upgrade')
  @HttpCode(HttpStatus.OK)
  async upgradePlan(
    @Headers('x-tenant-id') tenantId: string,
    @Body() body: { planName: string; currency?: 'USD' | 'CNY' },
  ) {
    await this.changePlan.execute({
      tenantId,
      newPlanName: body.planName,
      currency: body.currency === 'CNY' ? InvoiceCurrency.CNY : InvoiceCurrency.USD,
    });
    return { success: true };
  }

  @Post('subscription/cancel')
  @HttpCode(HttpStatus.OK)
  async cancelPlan(
    @Headers('x-tenant-id') tenantId: string,
    @Body() body: { immediate?: boolean },
  ) {
    await this.cancelSubscription.execute(tenantId, body.immediate ?? false);
    return { success: true };
  }

  @Get('usage/current')
  async getCurrentUsage(@Headers('x-tenant-id') tenantId: string) {
    return this.checkQuota.execute(tenantId);
  }
}
