import { getAuthenticatedUserId } from '../../../utils/auth';
import { REWARDS } from '../../../utils/economy';
import prisma from '../../../utils/prisma';
import { applyStreakMultiplier } from '../../../utils/streak';
import { getDayOfWeekFromGameDay } from '~/server/utils/gameDay';

interface CompletionResponse {
  message: string;
  reward: {
    coins: number;
    exp: number;
  };
  updatedCoins: number;
  updatedExp: number;
}

export default defineEventHandler(async (event): Promise<CompletionResponse> => {
  const userId = getAuthenticatedUserId(event);
  const habitId = parseInt(event.context.params?.id || '', 10);
  const body = await readBody(event);
  const gameDay: string = body.gameDay; // Expecting "YYYY-MM-DD"

  if (!gameDay || !/^\d{4}-\d{2}-\d{2}$/.test(gameDay)) {
    throw createError({ statusCode: 400, statusMessage: 'Invalid or missing gameDay property in request body. Expected YYYY-MM-DD.' });
  }

  if (isNaN(habitId)) {
    throw createError({ statusCode: 400, statusMessage: 'Invalid habit ID.' });
  }

  // Fetch user and habit in parallel
  const [user, habit] = await Promise.all([
    prisma.user.findUnique({ where: { id: userId } }),
    prisma.habit.findFirst({ where: { id: habitId, userId } })
  ]);

  if (!user) {
    throw createError({ statusCode: 401, statusMessage: 'User not found.' });
  }
  if (!habit) {
    throw createError({ statusCode: 404, statusMessage: 'Habit not found.' });
  }

  const appDayOfWeek = getDayOfWeekFromGameDay(gameDay);

  // For permanent users, ensure the habit is scheduled for today.
  // Anonymous users in the onboarding flow can complete it on any day.
  if (!user.isAnonymous) {
    if (!(habit.daysOfWeek as number[]).includes(appDayOfWeek)) {
      throw createError({ statusCode: 400, statusMessage: 'Habit is not active today.' });
    }
  }

  const existingCompletion = await prisma.habitCompletion.findFirst({
    where: {
      habitId: habitId,
      date: gameDay,
    },
  });

  if (existingCompletion) {
    throw createError({ statusCode: 409, statusMessage: 'Habit already completed today.' });
  }

  // Determine the reward based on user type
  let finalReward: { coins: number, exp: number };
  if (user.isAnonymous) {
    // Anonymous users in onboarding get a fixed reward from economy.ts
    finalReward = REWARDS.HABITS.ONBOARDING_COMPLETION;
  } else {
    // Permanent users get rewards based on streak
    // Streak defaults to 1 for multiplier if it's 0 or null
    const currentDailyStreak = user.dailyStreak && user.dailyStreak > 0 ? user.dailyStreak : 1;
    const baseReward = REWARDS.HABITS.COMPLETION;
    finalReward = applyStreakMultiplier(baseReward, currentDailyStreak);
  }

  const village = await prisma.village.findUnique({ where: { userId } });

  const [, updatedUser] = await prisma.$transaction([
    prisma.habitCompletion.create({
      data: {
        habitId: habitId,
        date: gameDay,
      },
    }),
    prisma.user.update({
      where: { id: userId },
      data: {
        coins: {
          increment: finalReward.coins,
        },
        exp: {
          increment: finalReward.exp,
        },
      },
    }),
    ...(village ? [prisma.villageEvent.create({
      data: {
        villageId: village.id,
        type: 'HABIT_COMPLETION',
        message: `Привычка "${habit.name}" выполнена, принеся вам ${finalReward.coins} монет и ${finalReward.exp} опыта.${user.dailyStreak > 1 ? ` Ваша серия визитов (x${user.dailyStreak}) увеличила награду!` : ''}`,
        coins: finalReward.coins,
        exp: finalReward.exp,
      }
    })] : []),
  ]);

  return {
    message: 'Habit completed successfully!',
    reward: finalReward,
    updatedCoins: updatedUser.coins,
    updatedExp: updatedUser.exp,
  };
});

