import type { FastifyPluginAsync } from "fastify";
import { z } from "zod";
import { requireAuth, requireRestaurantMember } from "../lib/auth.js";
import { supabase } from "../lib/supabase.js";
import { translateMenu, type TranslatableCategory } from "../lib/translator.js";

const SUPPORTED_LANGUAGES = ["en", "de", "ar", "ru", "fr"] as const;

const addLanguageSchema = z.object({
  code: z.enum(SUPPORTED_LANGUAGES),
});

async function getRestaurantMenuCategories(restaurantId: string): Promise<TranslatableCategory[]> {
  if (!supabase) return [];

  const { data: locations } = await supabase.from("locations").select("id").eq("restaurant_id", restaurantId);
  const locationIds = (locations ?? []).map((l) => l.id);
  if (locationIds.length === 0) return [];

  const { data: menus } = await supabase.from("menus").select("id").in("location_id", locationIds);
  const menuIds = (menus ?? []).map((m) => m.id);
  if (menuIds.length === 0) return [];

  const { data: categories } = await supabase
    .from("menu_categories")
    .select("id, name, menu_items(id, name, description)")
    .in("menu_id", menuIds);

  return (categories ?? []).map((cat) => ({
    id: cat.id,
    name: cat.name,
    items: (cat.menu_items ?? []).map((item: { id: string; name: string; description: string | null }) => ({
      id: item.id,
      name: item.name,
      description: item.description,
    })),
  }));
}

export const languagesRoutes: FastifyPluginAsync = async (app) => {
  // Add a language: translates all current menu content into it, then
  // enables it. New items created afterwards are translated on save
  // (see menu-categories.ts / menu-items.ts).
  app.post("/restaurants/:id/languages", async (req, reply) => {
    const userId = await requireAuth(req, reply);
    if (!userId || !supabase) return;

    const { id: restaurantId } = req.params as { id: string };
    const isMember = await requireRestaurantMember(userId, restaurantId);
    if (!isMember) return reply.code(403).send({ message: "forbidden" });

    const parsed = addLanguageSchema.safeParse(req.body);
    if (!parsed.success) {
      return reply.code(400).send({ message: "invalid language code", issues: parsed.error.issues });
    }
    const { code } = parsed.data;

    const { data: restaurant } = await supabase
      .from("restaurants")
      .select("enabled_languages")
      .eq("id", restaurantId)
      .single();

    const current: string[] = restaurant?.enabled_languages ?? ["tr"];
    if (current.includes(code)) {
      return reply.code(409).send({ message: "Bu dil zaten aktif." });
    }

    const categories = await getRestaurantMenuCategories(restaurantId);

    try {
      const translated = await translateMenu(categories, code);

      for (const cat of translated) {
        const original = categories.find((c) => c.id === cat.id);
        const { data: existingCatRow } = await supabase
          .from("menu_categories")
          .select("translations")
          .eq("id", cat.id)
          .single();
        await supabase
          .from("menu_categories")
          .update({
            translations: { ...(existingCatRow?.translations ?? {}), [code]: { name: cat.name } },
          })
          .eq("id", cat.id);

        for (const item of cat.items) {
          const { data: existingItemRow } = await supabase
            .from("menu_items")
            .select("translations")
            .eq("id", item.id)
            .single();
          await supabase
            .from("menu_items")
            .update({
              translations: {
                ...(existingItemRow?.translations ?? {}),
                [code]: { name: item.name, description: item.description },
              },
            })
            .eq("id", item.id);
        }
        void original;
      }
    } catch (err) {
      req.log.error(err);
      return reply.code(500).send({ message: "Menü çevirisi başarısız oldu", error: (err as Error).message });
    }

    const { data: updated } = await supabase
      .from("restaurants")
      .update({ enabled_languages: [...current, code] })
      .eq("id", restaurantId)
      .select("enabled_languages")
      .single();

    return reply.send({ enabledLanguages: updated?.enabled_languages ?? [...current, code] });
  });

  app.delete("/restaurants/:id/languages/:code", async (req, reply) => {
    const userId = await requireAuth(req, reply);
    if (!userId || !supabase) return;

    const { id: restaurantId, code } = req.params as { id: string; code: string };
    const isMember = await requireRestaurantMember(userId, restaurantId);
    if (!isMember) return reply.code(403).send({ message: "forbidden" });

    const { data: restaurant } = await supabase
      .from("restaurants")
      .select("enabled_languages")
      .eq("id", restaurantId)
      .single();

    const current: string[] = restaurant?.enabled_languages ?? ["tr"];
    const next = current.filter((c) => c !== code);

    const { data: updated } = await supabase
      .from("restaurants")
      .update({ enabled_languages: next })
      .eq("id", restaurantId)
      .select("enabled_languages")
      .single();

    return reply.send({ enabledLanguages: updated?.enabled_languages ?? next });
  });
};
