import {
  Message,
  MessageFlags,
  MessageComponentInteraction,
  ButtonInteraction,
  TextBasedChannel,
} from "discord.js";
import {
  ComponentType,
  TextInputStyle,
  ButtonStyle,
} from "discord-api-types/v10";
import type { CommandMessage } from "../../../core/types/commands";
import { hasManageGuildOrStaff } from "../../../core/lib/permissions";
import logger from "../../../core/lib/logger";
import type Amayo from "../../../core/client";

interface ItemEditorState {
  key: string;
  name?: string;
  description?: string;
  category?: string;
  icon?: string;
  stackable?: boolean;
  maxPerInventory?: number | null;
  tags: string[];
  props?: any;
  // Nueva propiedad para receta de crafteo
  recipe?: {
    enabled: boolean;
    ingredients: Array<{ itemKey: string; quantity: number }>;
    productQuantity: number;
  };
  // Derivado de props.global (solo owner puede establecerlo)
  isGlobal?: boolean;
}

export const command: CommandMessage = {
  name: "item-crear",
  type: "message",
  aliases: ["crear-item", "itemcreate"],
  cooldown: 10,
  description:
    "Crea un EconomyItem para este servidor con un pequeño editor interactivo.",
  category: "Economía",
  usage: "item-crear <key-única>",
  run: async (message: Message, args: string[], client: Amayo) => {
    const channel = message.channel as TextBasedChannel & { send: Function };
    const allowed = await hasManageGuildOrStaff(
      message.member,
      message.guild!.id,
      client.prisma
    );
    if (!allowed) {
      await (channel.send as any)({
        content: null,
        flags: 32768,
        components: [
          {
            type: 17,
            accent_color: 0xff0000,
            components: [
              {
                type: 10,
                content:
                  "❌ **Error de Permisos**\n└ No tienes permisos de ManageGuild ni rol de staff.",
              },
            ],
          },
        ],
        reply: { messageReference: message.id },
      });
      return;
    }

    const key = args[0]?.trim();
    if (!key) {
      await (channel.send as any)({
        content: null,
        flags: 32768,
        components: [
          {
            type: 17,
            accent_color: 0xffa500,
            components: [
              {
                type: 10,
                content:
                  "⚠️ **Uso Incorrecto**\n└ Uso: `!item-crear <key-única>`",
              },
            ],
          },
        ],
        reply: { messageReference: message.id },
      });
      return;
    }

    const guildId = message.guild!.id;

    const exists = await client.prisma.economyItem.findFirst({
      where: { key, guildId },
    });
    if (exists) {
      await (channel.send as any)({
        content: null,
        flags: 32768,
        components: [
          {
            type: 17,
            accent_color: 0xff0000,
            components: [
              {
                type: 10,
                content:
                  "❌ **Item Ya Existe**\n└ Ya existe un item con esa key en este servidor.",
              },
            ],
          },
        ],
        reply: { messageReference: message.id },
      });
      return;
    }

    const state: ItemEditorState = {
      key,
      tags: [],
      stackable: true,
      maxPerInventory: null,
      props: {},
      recipe: {
        enabled: false,
        ingredients: [],
        productQuantity: 1,
      },
      isGlobal: false,
    };

    const buildEditorDisplay = () => {
      const baseInfo = [
        `**Nombre:** ${state.name || "*Sin definir*"}`,
        `**Descripción:** ${state.description || "*Sin definir*"}`,
        `**Categoría:** ${state.category || "*Sin definir*"}`,
        `**Icon URL:** ${state.icon || "*Sin definir*"}`,
        `**Stackable:** ${state.stackable ? "Sí" : "No"}`,
        `**Máx. Inventario:** ${state.maxPerInventory ?? "Ilimitado"}`,
        `**Global:** ${state.isGlobal ? "Sí" : "No"}`,
      ].join("\n");

      const tagsInfo = `**Tags:** ${
        state.tags.length > 0 ? state.tags.join(", ") : "*Ninguno*"
      }`;
      const propsJson = JSON.stringify(state.props ?? {}, null, 2);
      const recipeInfo = state.recipe?.enabled
        ? `**Receta:** Habilitada (${state.recipe.ingredients.length} ingredientes → ${state.recipe.productQuantity} unidades)`
        : `**Receta:** Deshabilitada`;

      return {
        type: 17,
        accent_color: 0x00d9ff,
        components: [
          {
            type: 10,
            content: `# 🛠️ Editor de Item: \`${key}\``,
          },
          { type: 14, divider: true },
          {
            type: 10,
            content: baseInfo,
          },
          { type: 14, divider: true },
          {
            type: 10,
            content: tagsInfo,
          },
          { type: 14, divider: true },
          {
            type: 10,
            content: recipeInfo,
          },
          { type: 14, divider: true },
          {
            type: 10,
            content: `**Props (JSON):**\n\`\`\`json\n${propsJson}\n\`\`\``,
          },
        ],
      };
    };

    const buildEditorComponents = () => [
      buildEditorDisplay(),
      {
        type: 1,
        components: [
          {
            type: 2,
            style: ButtonStyle.Primary,
            label: "Base",
            custom_id: "it_base",
          },
          {
            type: 2,
            style: ButtonStyle.Secondary,
            label: "Tags",
            custom_id: "it_tags",
          },
          {
            type: 2,
            style: ButtonStyle.Secondary,
            label: "Receta",
            custom_id: "it_recipe",
          },
          {
            type: 2,
            style: ButtonStyle.Secondary,
            label: "Props (JSON)",
            custom_id: "it_props",
          },
        ],
      },
      {
        type: 1,
        components: [
          {
            type: 2,
            style: ButtonStyle.Success,
            label: "Guardar",
            custom_id: "it_save",
          },
          {
            type: 2,
            style: ButtonStyle.Danger,
            label: "Cancelar",
            custom_id: "it_cancel",
          },
        ],
      },
    ];

    const editorMsg = await (channel.send as any)({
      content: null,
      flags: 32768,
      components: buildEditorComponents(),
      reply: { messageReference: message.id },
    });

    const collector = editorMsg.createMessageComponentCollector({
      time: 30 * 60_000,
      filter: (i) => i.user.id === message.author.id,
    });

    collector.on("collect", async (i: MessageComponentInteraction) => {
      try {
        if (!i.isButton()) return;
        if (i.customId === "it_cancel") {
          await i.deferUpdate();
          await editorMsg.edit({
            content: null,
            flags: 32768,
            components: [
              {
                type: 17,
                accent_color: 0xff0000,
                components: [
                  {
                    type: 10,
                    content: "**❌ Editor cancelado.**",
                  },
                ],
              },
            ],
          });
          collector.stop("cancel");
          return;
        }
        if (i.customId === "it_base") {
          await showBaseModal(
            i as ButtonInteraction,
            state,
            editorMsg,
            buildEditorComponents
          );
          return;
        }
        if (i.customId === "it_tags") {
          await showTagsModal(
            i as ButtonInteraction,
            state,
            editorMsg,
            buildEditorComponents
          );
          return;
        }
        if (i.customId === "it_recipe") {
          await showRecipeModal(
            i as ButtonInteraction,
            state,
            editorMsg,
            buildEditorComponents,
            client
          );
          return;
        }
        if (i.customId === "it_props") {
          await showPropsModal(
            i as ButtonInteraction,
            state,
            editorMsg,
            buildEditorComponents
          );
          return;
        }
        if (i.customId === "it_save") {
          // Validar
          if (!state.name) {
            await i.reply({
              content: "❌ Falta el nombre del item (configura en Base).",
              flags: MessageFlags.Ephemeral,
            });
            return;
          }
          // Revisar bandera global en props (puede haberse puesto manualmente en JSON)
          state.isGlobal = !!state.props?.global;
          const BOT_OWNER_ID = "327207082203938818";
          if (state.isGlobal && i.user.id !== BOT_OWNER_ID) {
            await i.reply({
              content:
                "❌ No puedes crear ítems globales. Solo el owner del bot.",
              flags: MessageFlags.Ephemeral,
            });
            return;
          }

          // Si es global, usar guildId = null y verificar que no exista ya global con esa key
          let targetGuildId: string | null = message.guild!.id;
          if (state.isGlobal) {
            const existsGlobal = await client.prisma.economyItem.findFirst({
              where: { key: state.key, guildId: null },
            });
            if (existsGlobal) {
              await i.reply({
                content: "❌ Ya existe un ítem global con esa key.",
                flags: MessageFlags.Ephemeral,
              });
              return;
            }
            targetGuildId = null;
          }

          // Guardar item
          const createdItem = await client.prisma.economyItem.create({
            data: {
              guildId: targetGuildId,
              key: state.key,
              name: state.name!,
              description: state.description,
              category: state.category,
              icon: state.icon,
              stackable: state.stackable ?? true,
              maxPerInventory: state.maxPerInventory ?? undefined,
              tags: state.tags,
              props: state.props ?? {},
            },
          });

          // Guardar receta si está habilitada
          if (state.recipe?.enabled && state.recipe.ingredients.length > 0) {
            try {
              // Resolver itemIds de los ingredientes
              const ingredientsData: Array<{
                itemId: string;
                quantity: number;
              }> = [];
              for (const ing of state.recipe.ingredients) {
                const item = await client.prisma.economyItem.findFirst({
                  where: {
                    key: ing.itemKey,
                    OR: [{ guildId }, { guildId: null }],
                  },
                  orderBy: [{ guildId: "desc" }],
                });
                if (!item) {
                  throw new Error(`Ingrediente no encontrado: ${ing.itemKey}`);
                }
                ingredientsData.push({
                  itemId: item.id,
                  quantity: ing.quantity,
                });
              }

              // Crear la receta
              await client.prisma.itemRecipe.create({
                data: {
                  productItemId: createdItem.id,
                  productQuantity: state.recipe.productQuantity,
                  ingredients: {
                    create: ingredientsData,
                  },
                },
              });
            } catch (err: any) {
              logger.warn({ err }, "Error creando receta para item");
              await i.followUp({
                content: `⚠️ Item creado pero falló la receta: ${err.message}`,
                flags: MessageFlags.Ephemeral,
              });
            }
          }
          await i.reply({
            content: "✅ Item guardado!",
            flags: MessageFlags.Ephemeral,
          });
          await editorMsg.edit({
            content: null,
            flags: 32768,
            components: [
              {
                type: 17,
                accent_color: 0x00ff00,
                components: [
                  {
                    type: 10,
                    content: `✅ **Item Creado**\n└ Item \`${
                      state.key
                    }\` creado exitosamente.${
                      state.isGlobal ? " (Global)" : ""
                    }`,
                  },
                ],
              },
            ],
          });
          collector.stop("saved");
          return;
        }
      } catch (err) {
        logger.error({ err }, "item-crear interaction error");
        if (!i.deferred && !i.replied)
          await i.reply({
            content: "❌ Error procesando la acción.",
            flags: MessageFlags.Ephemeral,
          });
      }
    });

    collector.on("end", async (_c, r) => {
      if (r === "time") {
        try {
          await editorMsg.edit({
            content: null,
            flags: 32768,
            components: [
              {
                type: 17,
                accent_color: 0xffa500,
                components: [
                  {
                    type: 10,
                    content: "**⏰ Editor expirado.**",
                  },
                ],
              },
            ],
          });
        } catch {}
      }
    });
  },
};

async function showBaseModal(
  i: ButtonInteraction,
  state: ItemEditorState,
  editorMsg: any,
  buildComponents: () => any[]
) {
  const modal = {
    title: "Configuración base del Item",
    customId: "it_base_modal",
    components: [
      {
        type: ComponentType.Label,
        label: "Nombre",
        component: {
          type: ComponentType.TextInput,
          customId: "name",
          style: TextInputStyle.Short,
          required: true,
          value: state.name ?? "",
        },
      },
      {
        type: ComponentType.Label,
        label: "Descripción",
        component: {
          type: ComponentType.TextInput,
          customId: "desc",
          style: TextInputStyle.Paragraph,
          required: false,
          value: state.description ?? "",
        },
      },
      {
        type: ComponentType.Label,
        label: "Categoría",
        component: {
          type: ComponentType.TextInput,
          customId: "cat",
          style: TextInputStyle.Short,
          required: false,
          value: state.category ?? "",
        },
      },
      {
        type: ComponentType.Label,
        label: "Icon URL",
        component: {
          type: ComponentType.TextInput,
          customId: "icon",
          style: TextInputStyle.Short,
          required: false,
          value: state.icon ?? "",
        },
      },
      {
        type: ComponentType.Label,
        label: "Stackable y Máx inventario",
        component: {
          type: ComponentType.TextInput,
          customId: "stack_max",
          style: TextInputStyle.Short,
          required: false,
          placeholder: "true,10",
          value:
            state.stackable !== undefined
              ? `${state.stackable},${state.maxPerInventory ?? ""}`
              : "",
        },
      },
    ],
  } as const;

  await i.showModal(modal);
  try {
    const sub = await i.awaitModalSubmit({ time: 300_000 });
    const name = sub.components.getTextInputValue("name").trim();
    const desc = sub.components.getTextInputValue("desc").trim();
    const cat = sub.components.getTextInputValue("cat").trim();
    const icon = sub.components.getTextInputValue("icon").trim();
    const stackMax = sub.components.getTextInputValue("stack_max").trim();

    state.name = name;
    state.description = desc || undefined;
    state.category = cat || undefined;
    state.icon = icon || undefined;

    if (stackMax) {
      const [s, m] = stackMax.split(",");
      state.stackable = String(s).toLowerCase() !== "false";
      const mv = m?.trim();
      state.maxPerInventory = mv ? Math.max(0, parseInt(mv, 10) || 0) : null;
    }

    await sub.deferUpdate();
    await editorMsg.edit({
      content: null,
      flags: 32768,
      components: buildComponents(),
    });
  } catch {}
}

async function showTagsModal(
  i: ButtonInteraction,
  state: ItemEditorState,
  editorMsg: any,
  buildComponents: () => any[]
) {
  const modal = {
    title: "Tags del Item (separados por coma)",
    customId: "it_tags_modal",
    components: [
      {
        type: ComponentType.Label,
        label: "Tags",
        component: {
          type: ComponentType.TextInput,
          customId: "tags",
          style: TextInputStyle.Paragraph,
          required: false,
          value: state.tags.join(", "),
        },
      },
    ],
  } as const;
  await i.showModal(modal);
  try {
    const sub = await i.awaitModalSubmit({ time: 300_000 });
    const tags = sub.components.getTextInputValue("tags");
    state.tags = tags
      ? tags
          .split(",")
          .map((t) => t.trim())
          .filter(Boolean)
      : [];
    await sub.deferUpdate();
    await editorMsg.edit({
      content: null,
      flags: 32768,
      components: buildComponents(),
    });
  } catch {}
}

async function showPropsModal(
  i: ButtonInteraction,
  state: ItemEditorState,
  editorMsg: any,
  buildComponents: () => any[]
) {
  const template =
    state.props && Object.keys(state.props).length
      ? JSON.stringify(state.props)
      : JSON.stringify({
          tool: undefined,
          breakable: undefined,
          chest: undefined,
          eventCurrency: undefined,
          passiveEffects: [],
          mutationPolicy: undefined,
          craftingOnly: false,
          food: undefined,
          damage: undefined,
          defense: undefined,
          maxHpBonus: undefined,
        });
  const modal = {
    title: "Props (JSON) del Item",
    customId: "it_props_modal",
    components: [
      {
        type: ComponentType.Label,
        label: "JSON",
        component: {
          type: ComponentType.TextInput,
          customId: "props",
          style: TextInputStyle.Paragraph,
          required: false,
          value: template.slice(0, 4000),
        },
      },
    ],
  } as const;
  await i.showModal(modal);
  try {
    const sub = await i.awaitModalSubmit({ time: 300_000 });
    const raw = sub.components.getTextInputValue("props");
    if (raw) {
      try {
        const parsed = JSON.parse(raw);
        state.props = parsed;
        await sub.deferUpdate();
        await editorMsg.edit({
          content: null,
          flags: 32768,
          components: buildComponents(),
        });
      } catch (e) {
        await sub.reply({
          content: "❌ JSON inválido.",
          flags: MessageFlags.Ephemeral,
        });
      }
    } else {
      state.props = {};
      await sub.reply({
        content: "ℹ️ Props limpiados.",
        flags: MessageFlags.Ephemeral,
      });
      try {
        await editorMsg.edit({
          content: null,
          flags: 32768,
          components: buildComponents(),
        });
      } catch {}
    }
  } catch {}
}

async function showRecipeModal(
  i: ButtonInteraction,
  state: ItemEditorState,
  editorMsg: any,
  buildComponents: () => any[],
  client: Amayo
) {
  const currentRecipe = state.recipe || {
    enabled: false,
    ingredients: [],
    productQuantity: 1,
  };
  const ingredientsStr = currentRecipe.ingredients
    .map((ing) => `${ing.itemKey}:${ing.quantity}`)
    .join(", ");

  const modal = {
    title: "Receta de Crafteo",
    customId: "it_recipe_modal",
    components: [
      {
        type: ComponentType.Label,
        label: "Habilitar receta? (true/false)",
        component: {
          type: ComponentType.TextInput,
          customId: "enabled",
          style: TextInputStyle.Short,
          required: false,
          value: String(currentRecipe.enabled),
          placeholder: "true o false",
        },
      },
      {
        type: ComponentType.Label,
        label: "Cantidad que produce",
        component: {
          type: ComponentType.TextInput,
          customId: "quantity",
          style: TextInputStyle.Short,
          required: false,
          value: String(currentRecipe.productQuantity),
          placeholder: "1",
        },
      },
      {
        type: ComponentType.Label,
        label: "Ingredientes (itemKey:qty, ...)",
        component: {
          type: ComponentType.TextInput,
          customId: "ingredients",
          style: TextInputStyle.Paragraph,
          required: false,
          value: ingredientsStr,
          placeholder: "iron_ingot:3, wood_plank:1",
        },
      },
    ],
  } as const;

  await i.showModal(modal);
  try {
    const sub = await i.awaitModalSubmit({ time: 300_000 });
    const enabledStr = sub.components
      .getTextInputValue("enabled")
      .trim()
      .toLowerCase();
    const quantityStr = sub.components.getTextInputValue("quantity").trim();
    const ingredientsInput = sub.components
      .getTextInputValue("ingredients")
      .trim();

    const enabled = enabledStr === "true";
    const productQuantity = parseInt(quantityStr, 10) || 1;

    // Parsear ingredientes
    const ingredients: Array<{ itemKey: string; quantity: number }> = [];
    if (ingredientsInput && enabled) {
      const parts = ingredientsInput
        .split(",")
        .map((p) => p.trim())
        .filter(Boolean);
      for (const part of parts) {
        const [itemKey, qtyStr] = part.split(":").map((s) => s.trim());
        const qty = parseInt(qtyStr, 10);
        if (itemKey && qty > 0) {
          ingredients.push({ itemKey, quantity: qty });
        }
      }
    }

    state.recipe = { enabled, ingredients, productQuantity };

    await sub.deferUpdate();
    await editorMsg.edit({
      content: null,
      flags: 32768,
      components: buildComponents(),
    });
  } catch {}
}
