// index.js
import fs from "fs";
import path from "path";
import { fileURLToPath } from "url";
import { Client, GatewayIntentBits, Partials, PermissionsBitField, Collection, EmbedBuilder } from "discord.js";
import { QuickDB } from "quick.db"; 
import { sendLog } from "./logger.js";
import { punish, tryStripElevatedRoles } from "./utils/punish.js";

// حساب __dirname في ESM
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

// load config.json
const configPath = path.join(process.cwd(), "config.json");
const rawData = fs.readFileSync(configPath, "utf8");
const config = JSON.parse(rawData);

// QuickDB
const db = new QuickDB();

// Discord client
const client = new Client({
  intents: [
    GatewayIntentBits.Guilds,
    GatewayIntentBits.GuildMessages,
    GatewayIntentBits.MessageContent,
    GatewayIntentBits.GuildMembers
  ],
  partials: [Partials.Message, Partials.Channel, Partials.Reaction]
});

client.commands = new Collection();

// load commands dynamically
const commandsPath = path.join(__dirname, "commands");
if (fs.existsSync(commandsPath)) {
  for (const file of fs.readdirSync(commandsPath).filter(f => f.endsWith(".js"))) {
    const cmdModule = await import(path.join(commandsPath, file));
    const cmd = cmdModule.default || cmdModule;
    if (cmd && (cmd.name || cmd.data) && typeof cmd.execute === "function") {
      client.commands.set(cmd.name || cmd.data?.name, cmd);
    }
  }
}

// util: normalize arabic
const AR_DIACRITICS = /[\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06ED]/g;
function normalizeText(input = "") {
  let s = String(input || "").toLowerCase();
  s = s.replace(AR_DIACRITICS, "");
  s = s.replace(/[أإآا]/g, "ا").replace(/ى/g, "ي").replace(/ة/g, "ه").replace(/ؤ/g, "و").replace(/ئ/g, "ي");
  s = s.replace(/[^\p{L}\p{N}\s]/gu, " ").replace(/\s+/g, " ").trim();
  return s;
}
function makeWordBoundaryRegex(word) {
  const esc = word.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
  return new RegExp(`(?:^|[^\\p{L}\\p{N}])(${esc})(?=$|[^\\p{L}\\p{N}])`, "iu");
}

// DB helpers
async function getPointsOf(guildId, userId) {
  const legacyKey = `points_${userId}`;
  const guildKey = `points_${guildId}_${userId}`;
  const v1 = await db.get(guildKey) || 0;
  const v2 = await db.get(legacyKey) || 0;
  return Math.max(Number(v1 || 0), Number(v2 || 0));
}

async function setPointsOf(guildId, userId, val) {
  const guildKey = `points_${guildId}_${userId}`;
  await db.set(guildKey, Number(val));
}

// messageCreate handler
client.on("messageCreate", async (message) => {
  try {
    if (!message.guild || message.author.bot) return;

    const pref = config.prefix || "!";
    if (message.content.startsWith(pref)) {
      const args = message.content.slice(pref.length).trim().split(/\s+/);
      const cmdName = args.shift().toLowerCase();
      const cmd = client.commands.get(cmdName);
      if (cmd) {
        try {
          await cmd.execute(message, args, { db, client, config, getPointsOf, setPointsOf, sendLog, punish });
        } catch (err) {
          console.error("Command error", err);
          message.reply("❌ حدث خطأ أثناء تنفيذ الأمر.");
        }
      }
      return;
    }

    // spam detection
    const now = Date.now();
    const spamCfg = config.spam || { windowMs: 7000, maxMsgs: 5, points: 2 };
    const userKey = `spam.${message.guild.id}.${message.author.id}`;
    let arr = await db.get(userKey) || [];
    arr = arr.filter(ts => now - ts <= spamCfg.windowMs);
    arr.push(now);
    await db.set(userKey, arr);
    if (arr.length >= (spamCfg.maxMsgs || 5)) {
      await message.delete().catch(()=>{});
      const add = spamCfg.points || config.punishmentPoints?.spam || 2;
      let pts = await getPointsOf(message.guild.id, message.author.id);
      pts += add;
      await setPointsOf(message.guild.id, message.author.id, pts);
      await sendLog(client, `🔇 ${message.author.tag} => Spam detected. Points now: ${pts}`);
      try { 
        const spamEmbed = new EmbedBuilder()
          .setTitle("⚠️ تحذير سبام")
          .setDescription(`تم رصد سبام في **${message.guild.name}** — نقاطك الآن: **${pts}**`)
          .setColor("Red")
          .setTimestamp();
        await message.author.send({ embeds: [spamEmbed] });
      } catch(_) {}
      await punish(message.member, client, pts);
      return;
    }

    // blocked links
    const t = message.content.toLowerCase();
    const blocked = config.antiLinkBlocklist || ["discord.gg", "bit.ly"];
    if (blocked.some(d => t.includes(d))) {
      await message.delete().catch(()=>{});
      const add = config.punishmentPoints?.badWord || 2;
      let pts = await getPointsOf(message.guild.id, message.author.id);
      pts += add;
      await setPointsOf(message.guild.id, message.author.id, pts);
      await sendLog(client, `🔗 ${message.author.tag} posted blocked link. Points now: ${pts}`);
      try { 
        const linkEmbed = new EmbedBuilder()
          .setTitle("⚠️ تحذير روابط")
          .setDescription(`تم حذف رسالتك في **${message.guild.name}** — نقاطك الآن: **${pts}**`)
          .setColor("Red")
          .setTimestamp();
        await message.author.send({ embeds: [linkEmbed] });
      } catch(_) {}
      await punish(message.member, client, pts);
      return;
    }

    // badwords
    const raw = message.content;
    const match = (config.bannedWords || []).find(w => {
      try {
        if (!w || !w.trim()) return false;
        const re = makeWordBoundaryRegex(normalizeText(w));
        return re.test(normalizeText(raw));
      } catch (e) { return false; }
    });

    if (match) {
      await message.delete().catch(()=>{});

      // increase points
      const add = config.punishmentPoints?.badWord || 2;
      let pts = await getPointsOf(message.guild.id, message.author.id);
      pts += add;
      await setPointsOf(message.guild.id, message.author.id, pts);

      // 1️⃣ تحذير العضو في امبيد بدون ذكر الكلمة
      try {
        const warnEmbed = new EmbedBuilder()
          .setTitle("⚠️ تحذير")
          .setDescription(`تم حذف رسالتك بسبب محتوى مخالف.\nنقاطك الآن: **${pts}**`)
          .setColor("Red")
          .setTimestamp();
        await message.channel.send({ content: `<@${message.author.id}>`, embeds: [warnEmbed] });
        const dmEmbed = new EmbedBuilder()
          .setTitle("⚠️ تحذير")
          .setDescription(`تم حذف رسالتك في **${message.guild.name}** لأنها تحتوي على محتوى مخالف.\nنقاطك الآن: **${pts}**`)
          .setColor("Red")
          .setTimestamp();
        await message.author.send({ embeds: [dmEmbed] });
      } catch(_) {}

      // 2️⃣ Log في webhook باللون الأحمر مع ذكر الكلمة
      try {
        const logEmbed = new EmbedBuilder()
          .setTitle("🚨 كلمة ممنوعة تم استخدامها")
          .addFields(
            { name: "العضو", value: `<@${message.author.id}>`, inline: true },
            { name: "الكلمة", value: match, inline: true },
            { name: "نقاطه الحالية", value: `${pts}`, inline: true },
            { name: "السيرفر", value: message.guild.name, inline: false }
          )
          .setColor("Red")
          .setTimestamp();
        await sendLog(client, { embeds: [logEmbed] });
      } catch(_) {}

      // إزالة رولات مؤثرة لو العضو عنده صلاحيات
      if (message.member.permissions.has(PermissionsBitField.Flags.Administrator) ||
          message.member.permissions.has(PermissionsBitField.Flags.ManageGuild) ||
          message.member.permissions.has(PermissionsBitField.Flags.ManageRoles)) {
        await tryStripElevatedRoles(message.member, client);
      }

      // تطبيق العقوبة حسب النقاط
      await punish(message.member, client, pts);
      return;
    }

  } catch (e) {
    console.error("messageCreate handler error:", e);
  }
});

// ready
client.once("ready", () => {
  console.log(`✅ Logged in as ${client.user.tag}`);
});

// login
client.login(config.token).catch(err => {
  console.error("Failed to login. Check token in config.json", err);
});
