const { SlashCommandBuilder, EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle } = require('discord.js');

const QUEST_TYPES = {
  daily: { emoji: '☀️', name: 'Daily', color: 0xfbbf24 },
  weekly: { emoji: '📅', name: 'Weekly', color: 0x3b82f6 },
  special: { emoji: '⭐', name: 'Special', color: 0xa855f7 }
};

const OBJECTIVES = {
  messages: { emoji: '💬', name: 'Send Messages' },
  reactions: { emoji: '😄', name: 'Add Reactions' },
  voice_minutes: { emoji: '🎙️', name: 'Voice Chat (minutes)' },
  commands: { emoji: '⚡', name: 'Use Commands' },
  daily_claims: { emoji: '🎁', name: 'Claim Daily Rewards' },
  level_ups: { emoji: '📈', name: 'Level Up' },
  xp_earned: { emoji: '✨', name: 'Earn XP' }
};

module.exports = {
  data: new SlashCommandBuilder()
    .setName('quests')
    .setDescription('View and manage your quests')
    .addSubcommand(sub =>
      sub.setName('view')
        .setDescription('View available quests')
        .addStringOption(opt =>
          opt.setName('type')
            .setDescription('Filter by quest type')
            .setRequired(false)
            .addChoices(
              { name: '☀️ Daily', value: 'daily' },
              { name: '📅 Weekly', value: 'weekly' },
              { name: '⭐ Special', value: 'special' }
            )
        )
    )
    .addSubcommand(sub =>
      sub.setName('progress')
        .setDescription('View your quest progress')
    )
    .addSubcommand(sub =>
      sub.setName('claim')
        .setDescription('Claim rewards for completed quests')
        .addIntegerOption(opt =>
          opt.setName('quest_id')
            .setDescription('The ID of the quest to claim (leave empty to claim all)')
            .setRequired(false)
        )
    ),

  async execute(interaction, supabase) {
    if (!supabase) {
      return interaction.reply({ content: 'Database not configured.', ephemeral: true });
    }

    const subcommand = interaction.options.getSubcommand();

    switch (subcommand) {
      case 'view':
        return handleView(interaction, supabase);
      case 'progress':
        return handleProgress(interaction, supabase);
      case 'claim':
        return handleClaim(interaction, supabase);
    }
  }
};

async function getUserLink(supabase, discordId) {
  const { data } = await supabase
    .from('discord_links')
    .select('user_id')
    .eq('discord_id', discordId)
    .maybeSingle();
  return data;
}

async function handleView(interaction, supabase) {
  await interaction.deferReply();

  const guildId = interaction.guildId;
  const questType = interaction.options.getString('type');
  const now = new Date().toISOString();

  let query = supabase
    .from('quests')
    .select('*')
    .eq('guild_id', guildId)
    .eq('active', true)
    .or(`expires_at.is.null,expires_at.gt.${now}`)
    .or(`starts_at.is.null,starts_at.lte.${now}`)
    .order('quest_type')
    .order('xp_reward', { ascending: false });

  if (questType) {
    query = query.eq('quest_type', questType);
  }

  const { data: quests, error } = await query;

  if (error || !quests || quests.length === 0) {
    const embed = new EmbedBuilder()
      .setColor(0xfbbf24)
      .setTitle('📜 Quests')
      .setDescription(questType 
        ? `No active ${QUEST_TYPES[questType]?.name || questType} quests available.`
        : 'No active quests available right now.\n\nCheck back later or ask a server admin to add quests!')
      .setTimestamp();

    return interaction.editReply({ embeds: [embed] });
  }

  const link = await getUserLink(supabase, interaction.user.id);
  let userQuests = [];
  if (link) {
    const { data } = await supabase
      .from('user_quests')
      .select('*')
      .eq('user_id', link.user_id)
      .eq('guild_id', guildId);
    userQuests = data || [];
  }

  const userQuestMap = {};
  for (const uq of userQuests) {
    userQuestMap[uq.quest_id] = uq;
  }

  const groupedQuests = {};
  for (const quest of quests) {
    const type = quest.quest_type || 'special';
    if (!groupedQuests[type]) groupedQuests[type] = [];
    groupedQuests[type].push(quest);
  }

  const embed = new EmbedBuilder()
    .setColor(0x7c3aed)
    .setTitle('📜 Available Quests')
    .setDescription(link 
      ? 'Complete quests to earn XP rewards!'
      : 'Link your account with `/verify` to track quest progress!')
    .setThumbnail(interaction.guild.iconURL({ size: 128 }))
    .setFooter({ text: `Use /quests progress to see your progress • ${quests.length} quests available` })
    .setTimestamp();

  for (const [type, typeQuests] of Object.entries(groupedQuests)) {
    const typeInfo = QUEST_TYPES[type] || { emoji: '📋', name: type };
    const questList = typeQuests.slice(0, 5).map(quest => {
      const objInfo = OBJECTIVES[quest.objective] || { emoji: '🎯', name: quest.objective };
      const userQuest = userQuestMap[quest.id];
      
      let status = '';
      if (userQuest) {
        if (userQuest.claimed) {
          status = ' ✅ Claimed';
        } else if (userQuest.completed) {
          status = ' 🎁 Ready to claim!';
        } else {
          const percent = Math.min(100, Math.floor((userQuest.progress / quest.target_value) * 100));
          status = ` [${userQuest.progress}/${quest.target_value}] ${percent}%`;
        }
      }

      const expires = quest.expires_at 
        ? ` (ends <t:${Math.floor(new Date(quest.expires_at).getTime() / 1000)}:R>)` 
        : '';

      return `\`#${quest.id}\` **${quest.name}**${status}\n${objInfo.emoji} ${quest.target_value}x ${objInfo.name} → **${quest.xp_reward.toLocaleString()} XP**${expires}`;
    }).join('\n\n');

    const moreQuests = typeQuests.length > 5 ? `\n\n*...and ${typeQuests.length - 5} more*` : '';

    embed.addFields({
      name: `${typeInfo.emoji} ${typeInfo.name} Quests`,
      value: questList + moreQuests,
      inline: false
    });
  }

  await interaction.editReply({ embeds: [embed] });
}

async function handleProgress(interaction, supabase) {
  await interaction.deferReply();

  const guildId = interaction.guildId;
  const link = await getUserLink(supabase, interaction.user.id);

  if (!link) {
    return interaction.editReply({
      embeds: [
        new EmbedBuilder()
          .setColor(0xff6b6b)
          .setDescription('You need to link your account first! Use `/verify` to get started.')
      ]
    });
  }

  const now = new Date().toISOString();

  const { data: quests } = await supabase
    .from('quests')
    .select('*')
    .eq('guild_id', guildId)
    .eq('active', true)
    .or(`expires_at.is.null,expires_at.gt.${now}`)
    .or(`starts_at.is.null,starts_at.lte.${now}`);

  if (!quests || quests.length === 0) {
    return interaction.editReply({
      embeds: [
        new EmbedBuilder()
          .setColor(0xfbbf24)
          .setTitle('📊 Quest Progress')
          .setDescription('No active quests to track.')
      ]
    });
  }

  const questIds = quests.map(q => q.id);
  const { data: userQuests } = await supabase
    .from('user_quests')
    .select('*')
    .eq('user_id', link.user_id)
    .eq('guild_id', guildId)
    .in('quest_id', questIds);

  const userQuestMap = {};
  for (const uq of userQuests || []) {
    userQuestMap[uq.quest_id] = uq;
  }

  const inProgress = [];
  const completed = [];
  const notStarted = [];

  for (const quest of quests) {
    const uq = userQuestMap[quest.id];
    if (!uq) {
      notStarted.push(quest);
    } else if (uq.claimed) {
      continue;
    } else if (uq.completed) {
      completed.push({ quest, userQuest: uq });
    } else {
      inProgress.push({ quest, userQuest: uq });
    }
  }

  const embed = new EmbedBuilder()
    .setColor(0x7c3aed)
    .setTitle('📊 Your Quest Progress')
    .setThumbnail(interaction.user.displayAvatarURL({ size: 128 }))
    .setTimestamp();

  if (completed.length > 0) {
    const completedList = completed.slice(0, 5).map(({ quest }) => {
      const typeInfo = QUEST_TYPES[quest.quest_type] || { emoji: '📋' };
      return `${typeInfo.emoji} \`#${quest.id}\` **${quest.name}** - ${quest.xp_reward.toLocaleString()} XP 🎁`;
    }).join('\n');
    embed.addFields({
      name: '🎉 Ready to Claim!',
      value: completedList,
      inline: false
    });
  }

  if (inProgress.length > 0) {
    const progressList = inProgress.slice(0, 5).map(({ quest, userQuest }) => {
      const typeInfo = QUEST_TYPES[quest.quest_type] || { emoji: '📋' };
      const percent = Math.min(100, Math.floor((userQuest.progress / quest.target_value) * 100));
      const progressBar = createProgressBar(percent);
      return `${typeInfo.emoji} \`#${quest.id}\` **${quest.name}**\n${progressBar} ${userQuest.progress}/${quest.target_value} (${percent}%)`;
    }).join('\n\n');
    embed.addFields({
      name: '🔄 In Progress',
      value: progressList,
      inline: false
    });
  }

  if (notStarted.length > 0 && (completed.length + inProgress.length) < 5) {
    const notStartedList = notStarted.slice(0, 3).map(quest => {
      const typeInfo = QUEST_TYPES[quest.quest_type] || { emoji: '📋' };
      const objInfo = OBJECTIVES[quest.objective] || { emoji: '🎯', name: quest.objective };
      return `${typeInfo.emoji} \`#${quest.id}\` **${quest.name}** - ${quest.target_value}x ${objInfo.name}`;
    }).join('\n');
    embed.addFields({
      name: '📝 Not Started',
      value: notStartedList + (notStarted.length > 3 ? `\n*...and ${notStarted.length - 3} more*` : ''),
      inline: false
    });
  }

  if (completed.length === 0 && inProgress.length === 0 && notStarted.length === 0) {
    embed.setDescription('You\'ve completed all available quests! Check back later for more.');
  } else {
    const totalXP = completed.reduce((sum, { quest }) => sum + quest.xp_reward, 0);
    if (totalXP > 0) {
      embed.setDescription(`You have **${totalXP.toLocaleString()} XP** waiting to be claimed! Use \`/quests claim\``);
    }
  }

  embed.setFooter({ text: 'Use /quests claim to collect your rewards!' });

  await interaction.editReply({ embeds: [embed] });
}

async function handleClaim(interaction, supabase) {
  await interaction.deferReply();

  const guildId = interaction.guildId;
  const questId = interaction.options.getInteger('quest_id');

  const link = await getUserLink(supabase, interaction.user.id);
  if (!link) {
    return interaction.editReply({
      embeds: [
        new EmbedBuilder()
          .setColor(0xff6b6b)
          .setDescription('You need to link your account first! Use `/verify` to get started.')
      ]
    });
  }

  let query = supabase
    .from('user_quests')
    .select('*, quests(*)')
    .eq('user_id', link.user_id)
    .eq('guild_id', guildId)
    .eq('completed', true)
    .eq('claimed', false);

  if (questId) {
    query = query.eq('quest_id', questId);
  }

  const { data: claimable, error } = await query;

  if (error || !claimable || claimable.length === 0) {
    return interaction.editReply({
      embeds: [
        new EmbedBuilder()
          .setColor(0xfbbf24)
          .setTitle('No Rewards to Claim')
          .setDescription(questId 
            ? 'This quest is not completed or already claimed.'
            : 'You don\'t have any completed quests to claim.\n\nComplete quests to earn rewards!')
      ]
    });
  }

  let totalXP = 0;
  const claimedQuests = [];
  const rolesGranted = [];
  const now = new Date().toISOString();

  for (const uq of claimable) {
    const quest = uq.quests;
    if (!quest) continue;

    totalXP += quest.xp_reward;
    claimedQuests.push(quest.name);

    await supabase
      .from('user_quests')
      .update({ claimed: true, claimed_at: now })
      .eq('id', uq.id);

    if (quest.role_reward) {
      try {
        await interaction.member.roles.add(quest.role_reward);
        rolesGranted.push(quest.role_reward);
      } catch (e) {
        console.error('Failed to add quest role reward:', e.message);
      }
    }
  }

  if (totalXP > 0) {
    const { data: profile } = await supabase
      .from('user_profiles')
      .select('xp, total_xp_earned')
      .eq('id', link.user_id)
      .maybeSingle();

    const currentXP = profile?.xp || 0;
    const currentTotal = profile?.total_xp_earned || currentXP;

    await supabase
      .from('user_profiles')
      .update({ 
        xp: currentXP + totalXP, 
        total_xp_earned: currentTotal + totalXP,
        updated_at: now 
      })
      .eq('id', link.user_id);

    const { data: balance } = await supabase
      .from('user_balance')
      .select('*')
      .eq('user_id', link.user_id)
      .eq('guild_id', guildId)
      .maybeSingle();

    if (balance) {
      await supabase
        .from('user_balance')
        .update({ 
          balance: balance.balance + totalXP,
          total_earned: balance.total_earned + totalXP,
          updated_at: now 
        })
        .eq('user_id', link.user_id)
        .eq('guild_id', guildId);
    }
  }

  const embed = new EmbedBuilder()
    .setColor(0x00ff00)
    .setTitle('🎉 Rewards Claimed!')
    .setDescription(`You claimed rewards for **${claimable.length}** quest${claimable.length > 1 ? 's' : ''}!`)
    .addFields(
      { name: '💰 XP Earned', value: `**+${totalXP.toLocaleString()} XP**`, inline: true }
    )
    .setTimestamp();

  if (claimedQuests.length <= 5) {
    embed.addFields({
      name: '📜 Quests Completed',
      value: claimedQuests.map(n => `• ${n}`).join('\n'),
      inline: false
    });
  }

  if (rolesGranted.length > 0) {
    embed.addFields({
      name: '👑 Roles Granted',
      value: rolesGranted.map(r => `<@&${r}>`).join(', '),
      inline: false
    });
  }

  await interaction.editReply({ embeds: [embed] });
}

function createProgressBar(percent) {
  const filled = Math.floor(percent / 10);
  const empty = 10 - filled;
  return '█'.repeat(filled) + '░'.repeat(empty);
}
