import { Bot, Keyboard, InlineKeyboard, Api, InputFile } from "grammy";
import { config } from "./config";
import { UserModel } from "./models/User";
import { LeadModel } from "./models/Lead";
import { PortfolioModel } from "./models/Portfolio";
import { ServiceModel, parseFeatures, slugify } from "./models/Service";
import { ServiceCategoryModel } from "./models/ServiceCategory";

// ─── Cek admin ───────────────────────────────────────────────────────────────

function isAdmin(userId: number): boolean {
  return config.ADMIN_CHAT_ID.split(",")
    .map((id) => id.trim())
    .includes(String(userId));
}

// ─── Reply Keyboards (muncul di bawah kolom chat) ────────────────────────────

const KB_MAIN = new Keyboard()
  .text("📋 Leads").text("📊 Stats").row()
  .text("🗂 Portfolio").text("📤 Broadcast").row()
  .text("🛠 Layanan").row()
  .resized()
  .persistent();

const KB_PORTFOLIO = new Keyboard()
  .text("📋 Lihat Portfolio").text("➕ Tambah Portfolio").row()
  .text("🗑 Hapus Portfolio").text("🔙 Menu Utama").row()
  .resized()
  .persistent();

const KB_SERVICE = new Keyboard()
  .text("📋 Lihat Layanan").text("🗂 Kelola Kategori").row()
  .text("➕ Tambah Paket").text("✏️ Edit Paket").row()
  .text("🗑 Hapus Paket").text("🔙 Menu Utama").row()
  .resized()
  .persistent();

const KB_CANCEL = new Keyboard()
  .text("❌ Batalkan").row()
  .resized()
  .persistent();

// ─── State wizard tambah portfolio ──────────────────────────────────────────

type AddStep = "category" | "title" | "description" | "tech" | "demo" | "photo";
type AddPaketStep = "select_category" | "icon" | "name" | "description" | "price" | "features";
type EditPaketStep = "select_id" | "select_field" | "input_value";

type AdminStateType =
  | { type: "add_portfolio"; step: AddStep; category?: string; title?: string; description?: string; tech?: string; demoUrl?: string }
  | { type: "delete_portfolio" }
  | { type: "broadcast" }
  | { type: "add_paket"; step: AddPaketStep; categorySlug?: string; icon?: string; name?: string; description?: string; price?: string }
  | { type: "edit_paket"; step: EditPaketStep; paketId?: number; field?: string }
  | { type: "delete_paket" };

const adminStates = new Map<number, AdminStateType>();

// Inline keyboard pilih kategori saat tambah portfolio
const KB_CATEGORY_INLINE = new InlineKeyboard()
  .text("🌐 Website", "addcat_web")
  .text("🤖 Bot Telegram", "addcat_bot").row()
  .text("📱 Mobile App", "addcat_mobile");

// ─── Export untuk notifikasi dari main bot ───────────────────────────────────

export let adminBot: Bot | null = null;

export async function notifyAdmin(
  mainBotApi: Bot["api"],
  message: string,
  keyboard?: InlineKeyboard
) {
  const targets = config.ADMIN_CHAT_ID.split(",").map((id) => id.trim()).filter(Boolean);

  for (const chatId of targets) {
    // Coba admin bot dulu, fallback ke main bot jika gagal
    let sent = false;
    if (adminBot) {
      try {
        await adminBot.api.sendMessage(chatId, message, {
          parse_mode: "Markdown",
          reply_markup: keyboard,
        });
        sent = true;
      } catch (err: any) {
        console.error(`[notifyAdmin] Admin bot gagal kirim ke ${chatId}: ${err.message}`);
      }
    }

    if (!sent) {
      try {
        await mainBotApi.sendMessage(chatId, message, {
          parse_mode: "Markdown",
          reply_markup: keyboard,
        });
      } catch (err: any) {
        console.error(`[notifyAdmin] Main bot gagal kirim ke ${chatId}: ${err.message}`);
      }
    }
  }
}

// ─── Init ────────────────────────────────────────────────────────────────────

export function initAdminBot() {
  if (!config.ADMIN_BOT_TOKEN) {
    console.log("⚠️  ADMIN_BOT_TOKEN tidak diset, fitur admin bot dinonaktifkan.");
    return;
  }

  adminBot = new Bot(config.ADMIN_BOT_TOKEN);

  // ── /start ────────────────────────────────────────────────────────────────

  adminBot.command("start", async (ctx) => {
    if (!isAdmin(ctx.from!.id)) {
      await ctx.reply("⛔ Bot ini hanya untuk admin JD Technolody.");
      return;
    }
    await ctx.reply(
      `🛡 *Selamat datang di Admin Panel JD Technolody!*\n\n` +
        `Gunakan tombol di bawah untuk mengelola bot.`,
      { parse_mode: "Markdown", reply_markup: KB_MAIN }
    );
  });

  // ── Handler pesan teks ────────────────────────────────────────────────────

  adminBot.on("message:text", async (ctx) => {
    if (!isAdmin(ctx.from!.id)) return;

    const text = ctx.message.text.trim();
    const userId = ctx.from!.id;
    const state = adminStates.get(userId);

    // ── Tombol menu utama ─────────────────────────────────────────────────

    if (text === "📋 Leads") {
      adminStates.delete(userId);
      await showLeads(ctx);
      return;
    }

    if (text === "📊 Stats") {
      adminStates.delete(userId);
      await showStats(ctx);
      return;
    }

    if (text === "🗂 Portfolio") {
      adminStates.delete(userId);
      await ctx.reply("🗂 *Menu Portfolio*\nPilih aksi:", {
        parse_mode: "Markdown",
        reply_markup: KB_PORTFOLIO,
      });
      return;
    }

    if (text === "📤 Broadcast") {
      adminStates.delete(userId);
      adminStates.set(userId, { type: "broadcast" });
      await ctx.reply(
        "📤 *Broadcast Pesan*\n\nKetik pesan yang ingin dikirim ke semua user:\n_(emoji dan format *bold* didukung)_",
        { parse_mode: "Markdown", reply_markup: KB_CANCEL }
      );
      return;
    }

    if (text === "🛠 Layanan") {
      adminStates.delete(userId);
      await ctx.reply("🛠 *Menu Layanan*\nPilih aksi:", {
        parse_mode: "Markdown",
        reply_markup: KB_SERVICE,
      });
      return;
    }

    // ── Tombol menu portfolio ─────────────────────────────────────────────

    if (text === "📋 Lihat Portfolio") {
      adminStates.delete(userId);
      await showPortfolioList(ctx);
      return;
    }

    if (text === "➕ Tambah Portfolio") {
      adminStates.set(userId, { type: "add_portfolio", step: "category" });
      await ctx.reply(
        `➕ *Tambah Portfolio Baru*\n\nLangkah 1/6 — Pilih kategori:`,
        { parse_mode: "Markdown", reply_markup: KB_CANCEL }
      );
      await ctx.reply("Pilih kategori:", { reply_markup: KB_CATEGORY_INLINE });
      return;
    }

    if (text === "🗑 Hapus Portfolio") {
      adminStates.set(userId, { type: "delete_portfolio" });
      await showPortfolioList(ctx);
      await ctx.reply(
        "🗑 Ketik *ID* portfolio yang ingin dihapus:",
        { parse_mode: "Markdown", reply_markup: KB_CANCEL }
      );
      return;
    }

    // ── Tombol menu layanan ───────────────────────────────────────────────

    if (text === "📋 Lihat Layanan") {
      adminStates.delete(userId);
      await showServiceList(ctx);
      return;
    }

    if (text === "🗂 Kelola Kategori") {
      adminStates.delete(userId);
      await showCategoryList(ctx);
      return;
    }

    if (text === "➕ Tambah Paket") {
      adminStates.set(userId, { type: "add_paket", step: "select_category" });
      const cats = ServiceCategoryModel.getAll();
      const kb = new InlineKeyboard();
      cats.forEach((c, i) => {
        kb.text(`${c.icon} ${c.name}`, `addpaket_cat_${c.slug}`);
        if (i % 2 === 1) kb.row();
      });
      await ctx.reply(
        `➕ *Tambah Paket Baru*\n\nPilih kategori untuk paket ini:`,
        { parse_mode: "Markdown", reply_markup: KB_CANCEL }
      );
      await ctx.reply("Pilih kategori:", { reply_markup: kb });
      return;
    }

    if (text === "✏️ Edit Paket") {
      adminStates.set(userId, { type: "edit_paket", step: "select_id" });
      await showServiceList(ctx);
      await ctx.reply("✏️ Ketik *ID* paket yang ingin diedit:", {
        parse_mode: "Markdown",
        reply_markup: KB_CANCEL,
      });
      return;
    }

    if (text === "🗑 Hapus Paket") {
      adminStates.set(userId, { type: "delete_paket" });
      await showServiceList(ctx);
      await ctx.reply("🗑 Ketik *ID* paket yang ingin dihapus:", {
        parse_mode: "Markdown",
        reply_markup: KB_CANCEL,
      });
      return;
    }

    if (text === "🔙 Menu Utama") {
      adminStates.delete(userId);
      await ctx.reply("🏠 Menu Utama:", { reply_markup: KB_MAIN });
      return;
    }

    if (text === "❌ Batalkan") {
      adminStates.delete(userId);
      await ctx.reply("❌ Dibatalkan.", { reply_markup: KB_MAIN });
      return;
    }

    // ── Wizard state ──────────────────────────────────────────────────────

    if (!state) {
      await ctx.reply("Gunakan tombol menu di bawah.", { reply_markup: KB_MAIN });
      return;
    }

    // Broadcast
    if (state.type === "broadcast") {
      adminStates.delete(userId);
      await doBroadcast(ctx, text);
      return;
    }

    // Delete portfolio
    if (state.type === "delete_portfolio") {
      adminStates.delete(userId);
      const id = parseInt(text);
      if (isNaN(id)) {
        await ctx.reply("⚠️ ID tidak valid. Masukkan angka.", { reply_markup: KB_PORTFOLIO });
        return;
      }
      const deleted = PortfolioModel.delete(id);
      await ctx.reply(
        deleted ? `✅ Portfolio ID ${id} berhasil dihapus.` : `❌ Portfolio ID ${id} tidak ditemukan.`,
        { reply_markup: KB_PORTFOLIO }
      );
      return;
    }

    // Add portfolio wizard
    if (state.type === "add_portfolio") {
      await handleAddPortfolioText(ctx, userId, state, text);
      return;
    }

    // Delete paket
    if (state.type === "delete_paket") {
      adminStates.delete(userId);
      const id = parseInt(text);
      if (isNaN(id)) {
        await ctx.reply("⚠️ ID tidak valid. Masukkan angka.", { reply_markup: KB_SERVICE });
        return;
      }
      const deleted = ServiceModel.delete(id);
      await ctx.reply(
        deleted ? `✅ Paket ID ${id} berhasil dihapus.` : `❌ Paket ID ${id} tidak ditemukan.`,
        { reply_markup: KB_SERVICE }
      );
      return;
    }

    // Add paket wizard
    if (state.type === "add_paket") {
      await handleAddPaketText(ctx, userId, state, text);
      return;
    }

    // Edit paket wizard
    if (state.type === "edit_paket") {
      await handleEditPaketText(ctx, userId, state, text);
      return;
    }
  });

  // ── Handler foto & video portfolio ───────────────────────────────────────
  // PENTING: file_id di Telegram bersifat bot-specific.
  // Foto/video diterima admin bot harus di-re-upload via main bot
  // agar file_id yang tersimpan bisa dipakai oleh main bot.

  adminBot.on(["message:photo", "message:video"], async (ctx) => {
    if (!isAdmin(ctx.from!.id)) return;

    const userId = ctx.from!.id;
    const state = adminStates.get(userId);
    if (state?.type !== "add_portfolio" || state.step !== "photo") return;

    adminStates.delete(userId);
    await ctx.reply("⏳ Memproses media, mohon tunggu...");

    const isVideo = !!ctx.message.video;
    const mediaType: "photo" | "video" = isVideo ? "video" : "photo";

    // Ambil file_id dari admin bot
    const adminFileId = isVideo
      ? ctx.message.video!.file_id
      : ctx.message.photo![ctx.message.photo!.length - 1].file_id;

    try {
      // 1. Dapatkan file_path dari admin bot
      const fileInfo = await ctx.api.getFile(adminFileId);
      const fileUrl = new URL(
        `https://api.telegram.org/file/bot${config.ADMIN_BOT_TOKEN}/${fileInfo.file_path!}`
      );

      // 2. Re-upload via main bot agar dapat file_id yang valid untuk main bot
      const mainApi = new Api(config.BOT_TOKEN);
      let mainFileId: string;

      if (isVideo) {
        const sent = await mainApi.sendVideo(
          Number(config.ADMIN_CHAT_ID),
          new InputFile(fileUrl, "portfolio.mp4")
        );
        mainFileId = sent.video.file_id;
        try { await mainApi.deleteMessage(Number(config.ADMIN_CHAT_ID), sent.message_id); } catch (_) {}
      } else {
        const sent = await mainApi.sendPhoto(
          Number(config.ADMIN_CHAT_ID),
          new InputFile(fileUrl, "portfolio.jpg")
        );
        mainFileId = sent.photo[sent.photo.length - 1].file_id;
        try { await mainApi.deleteMessage(Number(config.ADMIN_CHAT_ID), sent.message_id); } catch (_) {}
      }

      // 3. Simpan dengan file_id dari main bot
      PortfolioModel.create({
        title: state.title!,
        category: state.category!,
        description: state.description!,
        tech: state.tech!,
        demoUrl: state.demoUrl,
        mediaFileId: mainFileId,
        mediaType,
      });

      await ctx.reply(
        `✅ *Portfolio berhasil ditambahkan!*\n\n` +
          `📌 *${state.title}*\n` +
          `🗂 Kategori: ${state.category}\n` +
          `⚙️ Tech: ${state.tech}\n` +
          `📎 Media: ${mediaType === "video" ? "🎥 Video" : "📸 Foto"}`,
        { parse_mode: "Markdown", reply_markup: KB_PORTFOLIO }
      );
    } catch (err: any) {
      // Jika re-upload gagal, simpan portfolio tanpa media
      PortfolioModel.create({
        title: state.title!,
        category: state.category!,
        description: state.description!,
        tech: state.tech!,
        demoUrl: state.demoUrl,
      });
      await ctx.reply(
        `⚠️ Portfolio disimpan *tanpa media* karena gagal proses: ${err.message}\n\n` +
          `Portfolio tetap bisa dilihat tanpa foto/video.`,
        { parse_mode: "Markdown", reply_markup: KB_PORTFOLIO }
      );
    }
  });

  // ── Callback: pilih kategori saat tambah portfolio ────────────────────────

  adminBot.callbackQuery(/^addcat_(web|bot|mobile)$/, async (ctx) => {
    await ctx.answerCallbackQuery();
    if (!isAdmin(ctx.from!.id)) return;

    const userId = ctx.from!.id;
    const category = ctx.match[1];
    const state = adminStates.get(userId);
    if (state?.type !== "add_portfolio") return;

    const catLabels: Record<string, string> = {
      web: "🌐 Website",
      bot: "🤖 Bot Telegram",
      mobile: "📱 Mobile App",
    };

    adminStates.set(userId, { ...state, step: "title", category });
    await ctx.editMessageText(`✅ Kategori: *${catLabels[category]}*`, {
      parse_mode: "Markdown",
    });
    await ctx.reply(
      `📝 *Langkah 2/6 — Judul Project*\n\nKetik nama project:`,
      { parse_mode: "Markdown", reply_markup: KB_CANCEL }
    );
  });

  // ── Callback: pilih kategori saat tambah paket ───────────────────────────

  adminBot.callbackQuery(/^addpaket_cat_(\w+)$/, async (ctx) => {
    await ctx.answerCallbackQuery();
    if (!isAdmin(ctx.from!.id)) return;

    const userId = ctx.from!.id;
    const categorySlug = ctx.match[1];
    const state = adminStates.get(userId);
    if (state?.type !== "add_paket") return;

    const cat = ServiceCategoryModel.getBySlug(categorySlug);
    adminStates.set(userId, { ...state, step: "icon", categorySlug });
    try { await ctx.deleteMessage(); } catch (_) {}
    await ctx.reply(
      `✅ Kategori: *${cat?.icon} ${cat?.name}*\n\nLangkah 1/5 — Ketik *emoji icon* paket:\n_Contoh: 📄 atau 🤖_`,
      { parse_mode: "Markdown", reply_markup: KB_CANCEL }
    );
  });

  // ── Callback: pilih field edit paket ─────────────────────────────────────

  adminBot.callbackQuery(/^editpaket_(icon|name|description|price|features|toggle)$/, async (ctx) => {
    await ctx.answerCallbackQuery();
    if (!isAdmin(ctx.from!.id)) return;

    const userId = ctx.from!.id;
    const field = ctx.match[1];
    const state = adminStates.get(userId);
    if (state?.type !== "edit_paket" || !state.paketId) return;

    if (field === "toggle") {
      const pkg = ServiceModel.getById(state.paketId);
      if (!pkg) { await ctx.reply("❌ Paket tidak ditemukan.", { reply_markup: KB_SERVICE }); return; }
      ServiceModel.update(state.paketId, { isActive: pkg.is_active ? 0 : 1 });
      adminStates.delete(userId);
      try { await ctx.deleteMessage(); } catch (_) {}
      await ctx.reply(
        `✅ Paket *${pkg.name}* sekarang ${pkg.is_active ? "⛔ dinonaktifkan" : "✅ diaktifkan"}.`,
        { parse_mode: "Markdown", reply_markup: KB_SERVICE }
      );
      return;
    }

    const fieldLabels: Record<string, string> = {
      icon: "Icon (emoji)", name: "Nama", description: "Deskripsi",
      price: "Harga", features: "Fitur-fitur",
    };

    adminStates.set(userId, { ...state, step: "input_value", field });
    try { await ctx.deleteMessage(); } catch (_) {}
    await ctx.reply(
      `✏️ Ketik nilai baru untuk *${fieldLabels[field]}*:` +
      (field === "features"
        ? `\n\n_Ketik satu fitur per baris. Contoh:_\n\`Login user\nKeranjang belanja\nPayment gateway\`\n_Ketik "skip" untuk kosongkan._`
        : ""),
      { parse_mode: "Markdown", reply_markup: KB_CANCEL }
    );
  });

  // ── Error handler ─────────────────────────────────────────────────────────

  adminBot.catch((err) => {
    console.error("Admin bot error:", err.message);
  });

  console.log("🛡  Admin bot berjalan...");
  adminBot.start();
}

// ─── Fungsi helper ────────────────────────────────────────────────────────────

async function handleAddPortfolioText(
  ctx: any,
  userId: number,
  state: Extract<AdminStateType, { type: "add_portfolio" }>,
  text: string
) {
  switch (state.step) {
    case "title":
      adminStates.set(userId, { ...state, step: "description", title: text });
      await ctx.reply(
        `📝 *Langkah 3/6 — Deskripsi*\n\nTulis deskripsi singkat project:`,
        { parse_mode: "Markdown", reply_markup: KB_CANCEL }
      );
      break;

    case "description":
      adminStates.set(userId, { ...state, step: "tech", description: text });
      await ctx.reply(
        `📝 *Langkah 4/6 — Teknologi*\n\nSebutkan teknologi yang digunakan, pisah dengan koma:\n_Contoh: React.js, Node.js, MongoDB_`,
        { parse_mode: "Markdown", reply_markup: KB_CANCEL }
      );
      break;

    case "tech":
      adminStates.set(userId, { ...state, step: "demo", tech: text });
      await ctx.reply(
        `📝 *Langkah 5/6 — Link Demo*\n\nMasukkan URL demo project:\n_Ketik "skip" jika tidak ada_`,
        { parse_mode: "Markdown", reply_markup: KB_CANCEL }
      );
      break;

    case "demo": {
      const demoUrl = text.toLowerCase() === "skip" ? undefined : text;
      adminStates.set(userId, { ...state, step: "photo", demoUrl });
      await ctx.reply(
        `📸 *Langkah 6/6 — Foto / Video Project*\n\nKirim screenshot foto atau video demo project:\n_Ketik "skip" jika tidak ada_`,
        { parse_mode: "Markdown", reply_markup: KB_CANCEL }
      );
      break;
    }

    case "photo":
      if (text.toLowerCase() === "skip") {
        adminStates.delete(userId);
        PortfolioModel.create({
          title: state.title!,
          category: state.category!,
          description: state.description!,
          tech: state.tech!,
          demoUrl: state.demoUrl,
        });
        await ctx.reply(
          `✅ *Portfolio berhasil ditambahkan!*\n\n` +
            `📌 *${state.title}*\n` +
            `🗂 Kategori: ${state.category}\n` +
            `⚙️ Tech: ${state.tech}`,
          { parse_mode: "Markdown", reply_markup: KB_PORTFOLIO }
        );
      } else {
        await ctx.reply(
          "⚠️ Silakan *kirim foto atau video* (screenshot project), atau ketik *skip* untuk melewati.",
          { parse_mode: "Markdown" }
        );
      }
      break;
  }
}

async function showStats(ctx: any) {
  const totalUsers = UserModel.countAll();
  const subscribedUsers = UserModel.countSubscribed();
  const todayUsers = UserModel.countToday();
  const totalLeads = LeadModel.countAll();
  const newLeads = LeadModel.countByStatus("new");
  const hotLeads = LeadModel.countHot();
  const todayLeads = LeadModel.countToday();
  const totalPortfolio = PortfolioModel.count();

  await ctx.reply(
    `📊 *Statistik JD Technolody*\n\n` +
      `👥 Total User: *${totalUsers}*\n` +
      `🔔 Subscribe: *${subscribedUsers}*\n` +
      `🆕 User Baru Hari ini: *${todayUsers}*\n\n` +
      `📋 Total Leads: *${totalLeads}*\n` +
      `🆕 Leads Baru: *${newLeads}*\n` +
      `🔥 Hot Leads: *${hotLeads}*\n` +
      `📅 Leads Hari ini: *${todayLeads}*\n\n` +
      `🗂 Total Portfolio: *${totalPortfolio}*`,
    { parse_mode: "Markdown", reply_markup: KB_MAIN }
  );
}

async function showLeads(ctx: any) {
  const leads = LeadModel.getNewLeads(10);

  if (leads.length === 0) {
    await ctx.reply("✅ Tidak ada leads baru saat ini.", { reply_markup: KB_MAIN });
    return;
  }

  await ctx.reply(`📋 *${leads.length} Lead Terbaru:*`, {
    parse_mode: "Markdown",
    reply_markup: KB_MAIN,
  });

  for (const lead of leads) {
    const hotBadge = lead.is_hot ? "🔥 *HOT LEAD*\n" : "";
    await ctx.reply(
      `${hotBadge}` +
        `👤 *${lead.name}*\n` +
        `📱 @${lead.username || "-"} | ID: ${lead.telegram_id}\n` +
        `📞 WA: ${lead.phone_number || "-"}\n` +
        `🛠 ${lead.service_type} | 💰 ${lead.budget}\n` +
        `📌 ${lead.project_name}\n` +
        `💡 ${lead.features}\n` +
        `⏰ Deadline: ${lead.deadline}\n` +
        `🕐 ${lead.created_at}`,
      {
        parse_mode: "Markdown",
        reply_markup: new InlineKeyboard()
          .url("💬 Chat", `tg://user?id=${lead.telegram_id}`)
          .url(
            "📞 WA",
            `https://wa.me/${lead.phone_number?.replace(/[^0-9]/g, "") || "0"}`
          ),
      }
    );
  }
}

async function showPortfolioList(ctx: any) {
  const items = PortfolioModel.getAll();

  if (items.length === 0) {
    await ctx.reply("Belum ada portfolio.", { reply_markup: KB_PORTFOLIO });
    return;
  }

  const catLabels: Record<string, string> = {
    web: "🌐",
    bot: "🤖",
    mobile: "📱",
  };

  const lines = items.map(
    (p) =>
      `ID *${p.id}* — ${catLabels[p.category] || ""} ${p.title}${p.media_file_id ? (p.media_type === "video" ? " 🎥" : " 📸") : ""}`
  );

  await ctx.reply(
    `🗂 *Daftar Portfolio (${items.length}):*\n\n` + lines.join("\n"),
    { parse_mode: "Markdown", reply_markup: KB_PORTFOLIO }
  );
}

async function showCategoryList(ctx: any) {
  const cats = ServiceCategoryModel.getAll();
  if (cats.length === 0) {
    await ctx.reply("Belum ada kategori.", { reply_markup: KB_SERVICE });
    return;
  }
  const lines = cats.map((c) => `ID *${c.id}* — ${c.icon} *${c.name}*\n   _${c.description}_`);
  await ctx.reply(
    `🗂 *Kategori Layanan (${cats.length}):*\n\n` + lines.join("\n\n"),
    { parse_mode: "Markdown", reply_markup: KB_SERVICE }
  );
}

async function showServiceList(ctx: any) {
  const cats = ServiceCategoryModel.getAll();
  const services = ServiceModel.getAll();

  if (services.length === 0) {
    await ctx.reply("Belum ada paket layanan.", { reply_markup: KB_SERVICE });
    return;
  }

  let text = `🛠 *Daftar Paket Layanan (${services.length}):*\n\n`;
  for (const cat of cats) {
    const pkgs = services.filter((s) => s.category_slug === cat.slug);
    if (pkgs.length === 0) continue;
    text += `${cat.icon} *${cat.name}:*\n`;
    text += pkgs
      .map((p) => `  ID *${p.id}* — ${p.icon} ${p.name} | ${p.price} ${p.is_active ? "✅" : "⛔"}`)
      .join("\n");
    text += "\n\n";
  }

  await ctx.reply(text, { parse_mode: "Markdown", reply_markup: KB_SERVICE });
}

async function handleAddPaketText(
  ctx: any,
  userId: number,
  state: Extract<AdminStateType, { type: "add_paket" }>,
  text: string
) {
  switch (state.step) {
    case "icon":
      adminStates.set(userId, { ...state, step: "name", icon: text });
      await ctx.reply(
        `${text} Icon tersimpan!\n\n📝 *Langkah 2/5 — Nama Paket*\n\nKetik nama paket:`,
        { parse_mode: "Markdown", reply_markup: KB_CANCEL }
      );
      break;

    case "name":
      adminStates.set(userId, { ...state, step: "description", name: text });
      await ctx.reply(
        `📝 *Langkah 3/5 — Deskripsi*\n\nKetik deskripsi singkat paket:`,
        { parse_mode: "Markdown", reply_markup: KB_CANCEL }
      );
      break;

    case "description":
      adminStates.set(userId, { ...state, step: "price", description: text });
      await ctx.reply(
        `📝 *Langkah 4/5 — Harga*\n\nKetik harga paket:\n_Contoh: Rp 300.000 atau Mulai Rp 1.000.000_`,
        { parse_mode: "Markdown", reply_markup: KB_CANCEL }
      );
      break;

    case "price":
      adminStates.set(userId, { ...state, step: "features", price: text });
      await ctx.reply(
        `📝 *Langkah 5/5 — Fitur-fitur*\n\n` +
        `Ketik satu fitur per baris:\n` +
        `_Contoh:_\n\`1 halaman responsif\nForm kontak\nWhatsApp button\`\n\n` +
        `_Ketik "skip" jika tidak ada fitur._`,
        { parse_mode: "Markdown", reply_markup: KB_CANCEL }
      );
      break;

    case "features": {
      adminStates.delete(userId);
      const features = text.toLowerCase() === "skip"
        ? []
        : text.split("\n").map((f) => f.trim()).filter(Boolean);
      const slug = `${state.categorySlug}_${slugify(state.name!)}`;
      const id = ServiceModel.create({
        categorySlug: state.categorySlug!,
        slug,
        icon: state.icon!,
        name: state.name!,
        description: state.description!,
        price: state.price!,
        features: JSON.stringify(features),
      });
      await ctx.reply(
        `✅ *Paket berhasil ditambahkan!*\n\n` +
        `${state.icon} *${state.name}*\n` +
        `💰 ${state.price}\n` +
        `✅ ${features.length} fitur\n` +
        `🔑 ID: *${id}*`,
        { parse_mode: "Markdown", reply_markup: KB_SERVICE }
      );
      break;
    }
  }
}

async function handleEditPaketText(
  ctx: any,
  userId: number,
  state: Extract<AdminStateType, { type: "edit_paket" }>,
  text: string
) {
  if (state.step === "select_id") {
    const id = parseInt(text);
    if (isNaN(id)) {
      await ctx.reply("⚠️ ID tidak valid. Masukkan angka.", { reply_markup: KB_SERVICE });
      return;
    }
    const pkg = ServiceModel.getById(id);
    if (!pkg) {
      adminStates.delete(userId);
      await ctx.reply(`❌ Paket ID ${id} tidak ditemukan.`, { reply_markup: KB_SERVICE });
      return;
    }
    adminStates.set(userId, { ...state, step: "select_field", paketId: id });
    const features = parseFeatures(pkg.features);
    const cat = ServiceCategoryModel.getBySlug(pkg.category_slug);
    await ctx.reply(
      `✏️ *Edit Paket ID ${id}*\n\n` +
      `Kategori: ${cat?.icon} ${cat?.name}\n` +
      `${pkg.icon} *${pkg.name}*\n` +
      `📝 ${pkg.description}\n` +
      `💰 ${pkg.price}\n` +
      `✅ ${features.length} fitur\n` +
      `Status: ${pkg.is_active ? "✅ Aktif" : "⛔ Nonaktif"}\n\n` +
      `Pilih field yang ingin diedit:`,
      {
        parse_mode: "Markdown",
        reply_markup: new InlineKeyboard()
          .text("Icon", "editpaket_icon").text("Nama", "editpaket_name").row()
          .text("Deskripsi", "editpaket_description").row()
          .text("Harga", "editpaket_price").text("Fitur", "editpaket_features").row()
          .text(pkg.is_active ? "⛔ Nonaktifkan" : "✅ Aktifkan", "editpaket_toggle"),
      }
    );
    return;
  }

  if (state.step === "input_value" && state.paketId && state.field) {
    adminStates.delete(userId);
    const field = state.field;
    const featuresJson = field === "features"
      ? JSON.stringify(
          text.toLowerCase() === "skip"
            ? []
            : text.split("\n").map((f) => f.trim()).filter(Boolean)
        )
      : undefined;
    const updated = ServiceModel.update(state.paketId, {
      icon: field === "icon" ? text : undefined,
      name: field === "name" ? text : undefined,
      description: field === "description" ? text : undefined,
      price: field === "price" ? text : undefined,
      features: featuresJson,
    });
    await ctx.reply(
      updated
        ? `✅ Paket ID ${state.paketId} berhasil diupdate.`
        : `❌ Gagal mengupdate paket.`,
      { reply_markup: KB_SERVICE }
    );
  }
}

async function doBroadcast(ctx: any, message: string) {
  const users = UserModel.getAllSubscribed();
  await ctx.reply(`📤 Broadcast ke ${users.length} user dimulai...`, {
    reply_markup: KB_MAIN,
  });

  // Broadcast dari main bot agar user mengenal nama bot utama
  const mainApi = new Api(config.BOT_TOKEN);
  let success = 0;
  let failed = 0;

  for (const user of users) {
    try {
      await mainApi.sendMessage(
        user.telegram_id,
        `📢 *Update dari JD Technolody*\n\n${message}`,
        { parse_mode: "Markdown" }
      );
      success++;
    } catch (_) {
      failed++;
    }
    await new Promise((r) => setTimeout(r, 50));
  }

  await ctx.reply(
    `✅ Broadcast selesai!\n✅ Berhasil: *${success}*\n❌ Gagal: *${failed}*`,
    { parse_mode: "Markdown", reply_markup: KB_MAIN }
  );
}
