const fs = require('fs');
const path = require('path');
const {
  Client,
  GatewayIntentBits,
  REST,
  Routes,
  SlashCommandBuilder,
  EmbedBuilder
} = require('discord.js');

const config = require('./config.json');

const dataPath = path.join(__dirname, 'database.json');

function readDatabase() {
  if (!fs.existsSync(dataPath)) {
    fs.writeFileSync(dataPath, JSON.stringify({ guilds: {} }, null, 2));
  }

  try {
    const raw = fs.readFileSync(dataPath, 'utf8');
    const parsed = JSON.parse(raw);

    if (!parsed || typeof parsed !== 'object') return { guilds: {} };
    if (!parsed.guilds || typeof parsed.guilds !== 'object') parsed.guilds = {};

    return parsed;
  } catch (error) {
    console.error('database.json okunamadı:', error);
    return { guilds: {} };
  }
}

function writeDatabase(db) {
  if (!db || typeof db !== 'object') db = { guilds: {} };
  if (!db.guilds || typeof db.guilds !== 'object') db.guilds = {};
  fs.writeFileSync(dataPath, JSON.stringify(db, null, 2));
}

const database = readDatabase();

if (!database.guilds || typeof database.guilds !== 'object') {
  database.guilds = {};
  writeDatabase(database);
}

const client = new Client({
  intents: [
    GatewayIntentBits.Guilds,
    GatewayIntentBits.GuildMessages,
    GatewayIntentBits.MessageContent,
    GatewayIntentBits.GuildMembers
  ]
});

const commands = [
  new SlashCommandBuilder().setName('seviyem').setDescription('Kendi seviyeni gösterir.'),
  new SlashCommandBuilder().setName('sıralama').setDescription('Seviye sıralamasını gösterir.')
].map((command) => command.toJSON());

const rest = new REST({ version: '10' }).setToken(config.token);

client.once('ready', async () => {
  console.log(`${client.user.tag} çalışıyor.`);

  if (!config.clientId || !config.guildId) {
    console.warn('clientId ya da guildId config.json içinde tanımlı değil; komutlar kayıt edilemeyecek.');
    return;
  }

  try {
    await rest.put(
      Routes.applicationGuildCommands(config.clientId, config.guildId),
      { body: commands }
    );
    console.log('Slash komutları güncellendi.');
  } catch (error) {
    console.error('Slash komutları kaydedilirken hata:', error);
  }
});

client.on('messageCreate', async (message) => {
  if (message.author.bot || !message.guild) return;
  if (message.guild.id !== config.guildId) return;
  if (!message.content.trim()) return;

  const guildId = message.guild.id;

  if (!database.guilds[guildId]) database.guilds[guildId] = {};
  const guildStore = database.guilds[guildId];

  if (!guildStore[message.author.id]) {
    guildStore[message.author.id] = { level: 0, progress: 0 };
  }

  let member = message.member;
  if (!member) {
    member = await message.guild.members.fetch(message.author.id).catch(() => null);
  }

  const userRecord = guildStore[message.author.id];
  userRecord.progress += 1;

  while (userRecord.progress >= (userRecord.level + 1) * 10) {
    userRecord.progress -= (userRecord.level + 1) * 10;
    userRecord.level += 1;
    await handleLevelUp(message.guild, member, userRecord.level);
  }

  writeDatabase(database);
});

client.on('interactionCreate', async (interaction) => {
  if (!interaction.isChatInputCommand()) return;

  if (!interaction.inGuild()) {
    await interaction.reply({ content: 'Bu komut sadece bir sunucuda kullanılabilir.', ephemeral: true });
    return;
  }

  const guildId = interaction.guildId;

  if (guildId !== config.guildId) {
    await interaction.reply({ content: 'Bu bot sadece yapılandırılan sunucuda çalışır.', ephemeral: true });
    return;
  }

  if (!database.guilds[guildId]) database.guilds[guildId] = {};
  const guildStore = database.guilds[guildId];

  if (!guildStore[interaction.user.id]) {
    guildStore[interaction.user.id] = { level: 0, progress: 0 };
    writeDatabase(database);
  }

  const userRecord = guildStore[interaction.user.id];
  const nextThreshold = (userRecord.level + 1) * 10;

  if (interaction.commandName === 'seviyem') {
    const embed = new EmbedBuilder()
      .setTitle('Seviye Durumu')
      .setColor(0x00ae86)
      .setDescription(
        `${interaction.user} şu anda **${userRecord.level}** seviyesinde.\n` +
        `Bir sonraki seviye için **${nextThreshold - userRecord.progress}** mesaj daha gerekiyor.\n` +
        `İlerleme: **${userRecord.progress}/${nextThreshold}**`
      )
      .setFooter({ text: 'Seviye sistemi her mesajda ilerler.' });

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

  if (interaction.commandName === 'sıralama') {
    const entries = Object.entries(guildStore);
    if (!entries.length) {
      await interaction.reply({ content: 'Henüz yeni seviyeliler yok.', ephemeral: true });
      return;
    }

    const sorted = entries
      .map(([userId, record]) => ({
        userId,
        level: record?.level ?? 0,
        progress: record?.progress ?? 0
      }))
      .sort((a, b) => {
        if (b.level !== a.level) return b.level - a.level;
        return b.progress - a.progress;
      })
      .slice(0, 10);

    const fields = await Promise.all(
      sorted.map(async (entry, index) => {
        const member = await interaction.guild.members.fetch(entry.userId).catch(() => null);
        const display = member ? member.displayName : `Bilinmeyen üye (${entry.userId})`;
        const threshold = (entry.level + 1) * 10;
        const nextNeed = threshold - entry.progress;

        return {
          name: `#${index + 1} • ${display}`,
          value: `Seviye **${entry.level}** · ${nextNeed} mesaj kaldı (${entry.progress}/${threshold})`
        };
      })
    );

    const embed = new EmbedBuilder()
      .setTitle('Sunucu Seviye Sıralaması (Top 10)')
      .setDescription('En çok seviyeye ulaşan 10 kişi listeleniyor.')
      .setColor(0x5b2cff)
      .setFooter({ text: 'Her mesajda ilerleme kaydedilir.' })
      .setTimestamp()
      .addFields(fields);

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

async function handleLevelUp(guild, member, newLevel) {
  const channelId = config.announcementChannelId;
  if (!channelId) return;

  const channel =
    guild.channels.cache.get(channelId) ||
    (await guild.channels.fetch(channelId).catch(() => null));
  if (!channel || !channel.isTextBased()) return;

  const roleReward = config.roleRewards ? config.roleRewards[newLevel] : null;
  let roleText = '';

  if (roleReward) {
    const role =
      guild.roles.cache.get(roleReward) ||
      (await guild.roles.fetch(roleReward).catch(() => null));
    if (role && member && !member.roles.cache.has(role.id)) {
      const added = await member.roles.add(role).catch(() => null);
      if (added) roleText = ` ve <@&${role.id}> rolü verildi`;
    }
  }

  await channel.send({
    content:
      `✨ **SEVİYE GÜNCELLENDİ**\n` +
      `${member ? member.toString() : 'Bir üye'} yeni bir seviyeye geçti.\n` +
      `Mevcut seviye: **${newLevel}**` +
      `${roleText ? `\n\n${roleText.replace(' ve ', '')}` : ''}`
  });
}

client.login(config.token);
