import type { FastifyPluginAsync } from "fastify";
import { z } from "zod";
import { requireAuth } from "../lib/auth.js";
import { getMenuIfMember } from "../lib/access.js";
import { supabase } from "../lib/supabase.js";

const updateMenuSchema = z.object({ name: z.string().min(1).max(120) });

export const menusRoutes: FastifyPluginAsync = async (app) => {
  app.get("/menus/:id", async (req, reply) => {
    const userId = await requireAuth(req, reply);
    if (!userId || !supabase) return;

    const { id } = req.params as { id: string };
    const access = await getMenuIfMember(userId, id);
    if (!access) return reply.code(404).send({ message: "not found" });

    const { data: categories, error } = await supabase
      .from("menu_categories")
      .select("*, menu_items(*)")
      .eq("menu_id", id)
      .order("sort_order", { ascending: true });

    if (error) {
      req.log.error(error);
      return reply.code(500).send({ message: "failed to load menu" });
    }

    return reply.send({ menu: access.menu, categories });
  });

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

    const { id } = req.params as { id: string };
    const access = await getMenuIfMember(userId, id);
    if (!access) return reply.code(404).send({ message: "not found" });

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

    const { data, error } = await supabase
      .from("menus")
      .update({ name: parsed.data.name, updated_at: new Date().toISOString() })
      .eq("id", id)
      .select()
      .single();

    if (error || !data) {
      req.log.error(error);
      return reply.code(500).send({ message: "failed to update menu" });
    }

    return reply.send(data);
  });

  app.post("/menus/:id/publish", async (req, reply) => {
    const userId = await requireAuth(req, reply);
    if (!userId || !supabase) return;

    const { id } = req.params as { id: string };
    const access = await getMenuIfMember(userId, id);
    if (!access) return reply.code(404).send({ message: "not found" });

    const { data, error } = await supabase
      .from("menus")
      .update({ is_published: true, published_at: new Date().toISOString() })
      .eq("id", id)
      .select()
      .single();

    if (error || !data) {
      req.log.error(error);
      return reply.code(500).send({ message: "failed to publish menu" });
    }

    return reply.send(data);
  });

  app.post("/menus/:id/unpublish", async (req, reply) => {
    const userId = await requireAuth(req, reply);
    if (!userId || !supabase) return;

    const { id } = req.params as { id: string };
    const access = await getMenuIfMember(userId, id);
    if (!access) return reply.code(404).send({ message: "not found" });

    const { data, error } = await supabase
      .from("menus")
      .update({ is_published: false })
      .eq("id", id)
      .select()
      .single();

    if (error || !data) {
      req.log.error(error);
      return reply.code(500).send({ message: "failed to unpublish menu" });
    }

    return reply.send(data);
  });

  // PRD §7 — AI import lands here in Faz 2; V1 manual flow builds the same
  // categories/items shape by hand via the routes below.
  app.post("/menus/import", async (_req, reply) => {
    return reply.code(501).send({ message: "not implemented — Faz 2" });
  });
};
