import { Injectable, NotFoundException } from '@nestjs/common';
import { Cron, CronExpression } from '@nestjs/schedule';
import { Logger } from '@nestjs/common';
import { PrismaService } from '../../database/prisma.service';
import { RewardEngine } from './reward-engine.service';
import { TransactionType } from '@prisma/client';

@Injectable()
export class TimeWalletService {
  private readonly logger = new Logger(TimeWalletService.name);

  constructor(
    private readonly prisma: PrismaService,
    private readonly rewardEngine: RewardEngine,
  ) {}

  async getWallet(childId: string) {
    const wallet = await this.prisma.timeWallet.findUnique({ where: { childId } });
    if (!wallet) throw new NotFoundException('Carteira não encontrada');
    return this.rewardEngine.getSnapshot(childId);
  }

  async getTransactions(childId: string, limit = 50) {
    const wallet = await this.prisma.timeWallet.findUnique({ where: { childId } });
    if (!wallet) throw new NotFoundException('Carteira não encontrada');

    return this.prisma.timeTransaction.findMany({
      where: { walletId: wallet.id },
      orderBy: { createdAt: 'desc' },
      take: limit,
    });
  }

  async manualAdjustment(
    childId: string,
    minutes: number,
    reason: string,
    guardianId: string,
  ) {
    if (minutes > 0) {
      await this.rewardEngine.credit({
        childId,
        minutes,
        type: TransactionType.MANUAL_ADJUSTMENT,
        description: `Ajuste manual pelo responsável: ${reason}`,
        metadata: { guardianId, reason },
      });
    } else {
      await this.rewardEngine.debit({
        childId,
        minutes: Math.abs(minutes),
        description: `Ajuste manual pelo responsável: ${reason}`,
        metadata: { guardianId, reason },
      });
    }
    return this.rewardEngine.getSnapshot(childId);
  }

  async updateWalletConfig(
    childId: string,
    config: {
      dailyFreeMinutes?: number;
      dailyConditionalMinutes?: number;
      dailyMaxMinutes?: number;
    },
  ) {
    return this.prisma.timeWallet.update({
      where: { childId },
      data: config,
    });
  }

  // Cron: meia-noite → reset diário de todas as carteiras
  @Cron('0 0 * * *')
  async dailyResetCron() {
    this.logger.log('[Cron] Iniciando reset diário das carteiras...');
    const children = await this.prisma.child.findMany({ select: { id: true } });
    for (const child of children) {
      try {
        await this.rewardEngine.processDailyReset(child.id);
      } catch (err) {
        this.logger.error(`Erro ao resetar carteira de ${child.id}:`, err);
      }
    }
    this.logger.log(`[Cron] Reset diário concluído para ${children.length} crianças`);
  }
}
