const { SlashCommandBuilder, EmbedBuilder, PermissionFlagsBits } = require('discord.js');

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

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-manage')
    .setDescription('Manage server quests (Admin only)')
    .setDefaultMemberPermissions(PermissionFlagsBits.Administrator)
    .addSubcommand(sub =>
      sub.setName('create')
        .setDescription('Create a new quest')
        .addStringOption(opt =>
          opt.setName('name')
            .setDescription('Quest name')
            .setRequired(true)
        )
        .addStringOption(opt =>
          opt.setName('type')
            .setDescription('Quest type')
            .setRequired(true)
            .addChoices(
              { name: '☀️ Daily', value: 'daily' },
              { name: '📅 Weekly', value: 'weekly' },
              { name: '⭐ Special', value: 'special' }
            )
        )
        .addStringOption(opt =>
          opt.setName('objective')
            .setDescription('What users need to do')
            .setRequired(true)
            .addChoices(
              { name: '💬 Send Messages', value: 'messages' },
              { name: '😄 Add Reactions', value: 'reactions' },
              { name: '🎙️ Voice Chat (minutes)', value: 'voice_minutes' },
              { name: '⚡ Use Commands', value: 'commands' },
              { name: '🎁 Claim Daily Rewards', value: 'daily_claims' },
              { name: '📈 Level Up', value: 'level_ups' },
              { name: '✨ Earn XP', value: 'xp_earned' }
            )
        )
        .addIntegerOption(opt =>
          opt.setName('target')
            .setDescription('Amount needed to complete')
            .setRequired(true)
            .setMinValue(1)
        )
        .addIntegerOption(opt =>
          opt.setName('xp_reward')
            .setDescription('XP reward for completion')
            .setRequired(true)
            .setMinValue(1)
        )
        .addStringOption(opt =>
          opt.setName('description')
            .setDescription('Quest description')
            .setRequired(false)
        )
        .addRoleOption(opt =>
          opt.setName('role_reward')
            .setDescription('Role to grant on completion')
            .setRequired(false)
        )
        .addBooleanOption(opt =>
          opt.setName('repeatable')
            .setDescription('Can users complete this quest multiple times?')
            .setRequired(false)
        )
        .addIntegerOption(opt =>
          opt.setName('duration_hours')
            .setDescription('Quest duration in hours (auto-expires)')
            .setRequired(false)
            .setMinValue(1)
        )
    )
    .addSubcommand(sub =>
      sub.setName('delete')
        .setDescription('Delete a quest')
        .addIntegerOption(opt =>
          opt.setName('quest_id')
            .setDescription('The ID of the quest to delete')
            .setRequired(true)
        )
    )
    .addSubcommand(sub =>
      sub.setName('edit')
        .setDescription('Edit an existing quest')
        .addIntegerOption(opt =>
          opt.setName('quest_id')
            .setDescription('The ID of the quest to edit')
            .setRequired(true)
        )
        .addStringOption(opt =>
          opt.setName('name')
            .setDescription('New quest name')
            .setRequired(false)
        )
        .addIntegerOption(opt =>
          opt.setName('xp_reward')
            .setDescription('New XP reward')
            .setRequired(false)
            .setMinValue(1)
        )
        .addIntegerOption(opt =>
          opt.setName('target')
            .setDescription('New target value')
            .setRequired(false)
            .setMinValue(1)
        )
        .addBooleanOption(opt =>
          opt.setName('active')
            .setDescription('Enable or disable the quest')
            .setRequired(false)
        )
    )
    .addSubcommand(sub =>
      sub.setName('list')
        .setDescription('List all quests')
    )
    .addSubcommand(sub =>
      sub.setName('reset')
        .setDescription('Reset quest progress for all users')
        .addIntegerOption(opt =>
          opt.setName('quest_id')
            .setDescription('The ID of the quest to reset (leave empty to reset all)')
            .setRequired(false)
        )
        .addStringOption(opt =>
          opt.setName('type')
            .setDescription('Reset all quests of a type')
            .setRequired(false)
            .addChoices(
              { name: '☀️ Daily', value: 'daily' },
              { name: '📅 Weekly', value: 'weekly' }
            )
        )
    )
    .addSubcommand(sub =>
      sub.setName('stats')
        .setDescription('View quest statistics')
    ),

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

    const subcommand = interaction.options.getSubcommand();

    switch (subcommand) {
      case 'create':
        return handleCreate(interaction, supabase);
      case 'delete':
        return handleDelete(interaction, supabase);
      case 'edit':
        return handleEdit(interaction, supabase);
      case 'list':
        return handleList(interaction, supabase);
      case 'reset':
        return handleReset(interaction, supabase);
      case 'stats':
        return handleStats(interaction, supabase);
    }
  }
};

async function handleCreate(interaction, supabase) {
  await interaction.deferReply({ ephemeral: true });

  const guildId = interaction.guildId;
  const name = interaction.options.getString('name');
  const questType = interaction.options.getString('type');
  const objective = interaction.options.getString('objective');
  const target = interaction.options.getInteger('target');
  const xpReward = interaction.options.getInteger('xp_reward');
  const description = interaction.options.getString('description') || '';
  const roleReward = interaction.options.getRole('role_reward');
  const repeatable = interaction.options.getBoolean('repeatable') || false;
  const durationHours = interaction.options.getInteger('duration_hours');

  let expiresAt = null;
  if (durationHours) {
    expiresAt = new Date(Date.now() + durationHours * 60 * 60 * 1000).toISOString();
  }

  try {
    const { data: newQuest, error } = await supabase
      .from('quests')
      .insert({
        guild_id: guildId,
        name: name,
        description: description,
        quest_type: questType,
        objective: objective,
        target_value: target,
        xp_reward: xpReward,
        role_reward: roleReward?.id || null,
        repeatable: repeatable,
        starts_at: new Date().toISOString(),
        expires_at: expiresAt,
        active: true
      })
      .select()
      .single();

    if (error) throw error;

    const typeInfo = QUEST_TYPES[questType] || { emoji: '📋', name: questType };
    const objInfo = OBJECTIVES[objective] || { emoji: '🎯', name: objective };

    const embed = new EmbedBuilder()
      .setColor(0x00ff00)
      .setTitle('✅ Quest Created')
      .addFields(
        { name: 'Quest ID', value: `#${newQuest.id}`, inline: true },
        { name: 'Name', value: name, inline: true },
        { name: 'Type', value: `${typeInfo.emoji} ${typeInfo.name}`, inline: true },
        { name: 'Objective', value: `${objInfo.emoji} ${target}x ${objInfo.name}`, inline: true },
        { name: 'XP Reward', value: `${xpReward.toLocaleString()} XP`, inline: true },
        { name: 'Repeatable', value: repeatable ? 'Yes' : 'No', inline: true }
      );

    if (description) {
      embed.addFields({ name: 'Description', value: description, inline: false });
    }

    if (roleReward) {
      embed.addFields({ name: 'Role Reward', value: `<@&${roleReward.id}>`, inline: true });
    }

    if (expiresAt) {
      embed.addFields({ 
        name: 'Expires', 
        value: `<t:${Math.floor(new Date(expiresAt).getTime() / 1000)}:R>`, 
        inline: true 
      });
    }

    embed.setTimestamp();

    await interaction.editReply({ embeds: [embed] });
  } catch (error) {
    console.error('Quest create error:', error);
    await interaction.editReply({
      embeds: [
        new EmbedBuilder()
          .setColor(0xff0000)
          .setDescription('Failed to create quest.')
      ]
    });
  }
}

async function handleDelete(interaction, supabase) {
  await interaction.deferReply({ ephemeral: true });

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

  try {
    const { data: quest } = await supabase
      .from('quests')
      .select('*')
      .eq('id', questId)
      .eq('guild_id', guildId)
      .maybeSingle();

    if (!quest) {
      return interaction.editReply({
        embeds: [
          new EmbedBuilder()
            .setColor(0xff6b6b)
            .setDescription('Quest not found.')
        ]
      });
    }

    await supabase
      .from('quests')
      .delete()
      .eq('id', questId)
      .eq('guild_id', guildId);

    await interaction.editReply({
      embeds: [
        new EmbedBuilder()
          .setColor(0x00ff00)
          .setTitle('🗑️ Quest Deleted')
          .setDescription(`**${quest.name}** has been deleted.`)
          .setTimestamp()
      ]
    });
  } catch (error) {
    console.error('Quest delete error:', error);
    await interaction.editReply({
      embeds: [
        new EmbedBuilder()
          .setColor(0xff0000)
          .setDescription('Failed to delete quest.')
      ]
    });
  }
}

async function handleEdit(interaction, supabase) {
  await interaction.deferReply({ ephemeral: true });

  const guildId = interaction.guildId;
  const questId = interaction.options.getInteger('quest_id');
  const newName = interaction.options.getString('name');
  const newXpReward = interaction.options.getInteger('xp_reward');
  const newTarget = interaction.options.getInteger('target');
  const active = interaction.options.getBoolean('active');

  try {
    const { data: quest } = await supabase
      .from('quests')
      .select('*')
      .eq('id', questId)
      .eq('guild_id', guildId)
      .maybeSingle();

    if (!quest) {
      return interaction.editReply({
        embeds: [
          new EmbedBuilder()
            .setColor(0xff6b6b)
            .setDescription('Quest not found.')
        ]
      });
    }

    const updates = { updated_at: new Date().toISOString() };
    const changes = [];

    if (newName !== null) {
      updates.name = newName;
      changes.push(`Name: ${quest.name} → ${newName}`);
    }
    if (newXpReward !== null) {
      updates.xp_reward = newXpReward;
      changes.push(`XP Reward: ${quest.xp_reward} → ${newXpReward}`);
    }
    if (newTarget !== null) {
      updates.target_value = newTarget;
      changes.push(`Target: ${quest.target_value} → ${newTarget}`);
    }
    if (active !== null) {
      updates.active = active;
      changes.push(`Active: ${quest.active} → ${active}`);
    }

    if (changes.length === 0) {
      return interaction.editReply({
        embeds: [
          new EmbedBuilder()
            .setColor(0xfbbf24)
            .setDescription('No changes specified.')
        ]
      });
    }

    await supabase
      .from('quests')
      .update(updates)
      .eq('id', questId);

    await interaction.editReply({
      embeds: [
        new EmbedBuilder()
          .setColor(0x00ff00)
          .setTitle('✏️ Quest Updated')
          .setDescription(`**${quest.name}** has been updated.`)
          .addFields({ name: 'Changes', value: changes.join('\n') })
          .setTimestamp()
      ]
    });
  } catch (error) {
    console.error('Quest edit error:', error);
    await interaction.editReply({
      embeds: [
        new EmbedBuilder()
          .setColor(0xff0000)
          .setDescription('Failed to edit quest.')
      ]
    });
  }
}

async function handleList(interaction, supabase) {
  await interaction.deferReply({ ephemeral: true });

  const guildId = interaction.guildId;

  try {
    const { data: quests, error } = await supabase
      .from('quests')
      .select('*')
      .eq('guild_id', guildId)
      .order('quest_type')
      .order('created_at', { ascending: false });

    if (error || !quests || quests.length === 0) {
      return interaction.editReply({
        embeds: [
          new EmbedBuilder()
            .setColor(0xfbbf24)
            .setTitle('📋 Server Quests')
            .setDescription('No quests created yet.\n\nUse `/quests-manage create` to add quests.')
        ]
      });
    }

    const embed = new EmbedBuilder()
      .setColor(0x7c3aed)
      .setTitle('📋 Server Quests (Admin View)')
      .setDescription(`Total quests: **${quests.length}**`)
      .setTimestamp();

    const questLines = quests.map(quest => {
      const status = quest.active ? '✅' : '❌';
      const typeInfo = QUEST_TYPES[quest.quest_type] || { emoji: '📋' };
      const objInfo = OBJECTIVES[quest.objective] || { emoji: '🎯', name: quest.objective };
      const expires = quest.expires_at && new Date(quest.expires_at) < new Date() ? ' ⏰' : '';
      return `${status} ${typeInfo.emoji} \`#${quest.id}\` **${quest.name}** - ${objInfo.emoji} ${quest.target_value}x → ${quest.xp_reward} XP${expires}`;
    });

    const chunks = [];
    let current = '';
    for (const line of questLines) {
      if ((current + '\n' + line).length > 1000) {
        chunks.push(current);
        current = line;
      } else {
        current = current ? current + '\n' + line : line;
      }
    }
    if (current) chunks.push(current);

    for (let i = 0; i < Math.min(chunks.length, 5); i++) {
      embed.addFields({
        name: i === 0 ? 'Quests' : '\u200b',
        value: chunks[i],
        inline: false
      });
    }

    await interaction.editReply({ embeds: [embed] });
  } catch (error) {
    console.error('Quest list error:', error);
    await interaction.editReply({
      embeds: [
        new EmbedBuilder()
          .setColor(0xff0000)
          .setDescription('Failed to list quests.')
      ]
    });
  }
}

async function handleReset(interaction, supabase) {
  await interaction.deferReply({ ephemeral: true });

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

  try {
    let deleteQuery = supabase
      .from('user_quests')
      .delete()
      .eq('guild_id', guildId);

    let description = '';

    if (questId) {
      deleteQuery = deleteQuery.eq('quest_id', questId);
      description = `Progress reset for quest #${questId}`;
    } else if (questType) {
      const { data: quests } = await supabase
        .from('quests')
        .select('id')
        .eq('guild_id', guildId)
        .eq('quest_type', questType);
      
      if (quests && quests.length > 0) {
        deleteQuery = deleteQuery.in('quest_id', quests.map(q => q.id));
        description = `Progress reset for all ${QUEST_TYPES[questType]?.name || questType} quests`;
      } else {
        return interaction.editReply({
          embeds: [
            new EmbedBuilder()
              .setColor(0xfbbf24)
              .setDescription('No quests found for that type.')
          ]
        });
      }
    } else {
      description = 'Progress reset for all quests';
    }

    await deleteQuery;

    await interaction.editReply({
      embeds: [
        new EmbedBuilder()
          .setColor(0x00ff00)
          .setTitle('🔄 Quest Progress Reset')
          .setDescription(description)
          .setTimestamp()
      ]
    });
  } catch (error) {
    console.error('Quest reset error:', error);
    await interaction.editReply({
      embeds: [
        new EmbedBuilder()
          .setColor(0xff0000)
          .setDescription('Failed to reset quest progress.')
      ]
    });
  }
}

async function handleStats(interaction, supabase) {
  await interaction.deferReply({ ephemeral: true });

  const guildId = interaction.guildId;

  try {
    const { data: quests } = await supabase
      .from('quests')
      .select('*')
      .eq('guild_id', guildId);

    const { data: userQuests } = await supabase
      .from('user_quests')
      .select('*, quests(*)')
      .eq('guild_id', guildId);

    const totalQuests = quests?.length || 0;
    const activeQuests = quests?.filter(q => q.active).length || 0;
    const totalCompletions = userQuests?.filter(uq => uq.completed).length || 0;
    const totalClaimed = userQuests?.filter(uq => uq.claimed).length || 0;
    const uniqueParticipants = new Set(userQuests?.map(uq => uq.user_id)).size;
    const totalXPRewarded = userQuests
      ?.filter(uq => uq.claimed && uq.quests)
      .reduce((sum, uq) => sum + (uq.quests.xp_reward || 0), 0) || 0;

    const questCompletions = {};
    for (const uq of userQuests || []) {
      if (uq.completed && uq.quests) {
        const name = uq.quests.name;
        questCompletions[name] = (questCompletions[name] || 0) + 1;
      }
    }

    const topQuests = Object.entries(questCompletions)
      .sort(([, a], [, b]) => b - a)
      .slice(0, 5)
      .map(([name, count], i) => `${i + 1}. **${name}** (${count} completions)`)
      .join('\n');

    const embed = new EmbedBuilder()
      .setColor(0x7c3aed)
      .setTitle('📊 Quest Statistics')
      .addFields(
        { name: '📜 Total Quests', value: `${totalQuests} (${activeQuests} active)`, inline: true },
        { name: '✅ Total Completions', value: totalCompletions.toString(), inline: true },
        { name: '🎁 Total Claims', value: totalClaimed.toString(), inline: true },
        { name: '👥 Participants', value: uniqueParticipants.toString(), inline: true },
        { name: '💰 XP Rewarded', value: totalXPRewarded.toLocaleString(), inline: true }
      )
      .setTimestamp();

    if (topQuests) {
      embed.addFields({ name: '🏆 Most Completed Quests', value: topQuests, inline: false });
    }

    await interaction.editReply({ embeds: [embed] });
  } catch (error) {
    console.error('Quest stats error:', error);
    await interaction.editReply({
      embeds: [
        new EmbedBuilder()
          .setColor(0xff0000)
          .setDescription('Failed to get statistics.')
      ]
    });
  }
}
