import { NextResponse } from "next/server";
import { createClient } from "@/lib/supabase-server";
import { createAdminClient } from "@/lib/supabase-admin";
import { isOwnerUser } from "@/lib/owner-auth";
import { faxinarSlug } from "@/lib/faxina-html";
import { CAMPOS_DA_TRILHA, texto } from "@/lib/help";

/**
 * As trilhas: uma ordem pronta de artigos, atravessando seções.
 *
 * Existem porque a pergunta de quem chega raramente é "onde fica o PDV". É
 * "por onde eu começo". A trilha responde isso com uma sequência, e guarda o
 * progresso por PESSOA — duas pessoas da mesma gráfica andam em ritmos
 * diferentes, e progresso por empresa marcaria como lido o que só um leu.
 */

export const dynamic = "force-dynamic";

async function conferirDono() {
  const supabase = await createClient();
  const {
    data: { user },
  } = await supabase.auth.getUser();
  if (!user || !isOwnerUser({ id: user.id, email: user.email })) return null;
  return user;
}

function semPermissao() {
  return NextResponse.json({ error: "Sem permissão." }, { status: 403 });
}

export async function GET() {
  if (!(await conferirDono())) return semPermissao();

  const admin = createAdminClient();
  const { data, error } = await admin
    .from("help_paths")
    .select(CAMPOS_DA_TRILHA)
    .order("position", { ascending: true });
  if (error) return NextResponse.json({ error: "Não foi possível carregar as trilhas." }, { status: 400 });

  const { data: passos } = await admin
    .from("help_path_steps")
    .select("path_id,article_id,position")
    .order("position", { ascending: true });

  const porTrilha = new Map<string, Array<{ article_id: string; position: number }>>();
  for (const p of passos ?? []) {
    const lista = porTrilha.get(p.path_id) ?? [];
    lista.push({ article_id: p.article_id, position: p.position });
    porTrilha.set(p.path_id, lista);
  }

  const trilhas = (data ?? []).map((t) => ({ ...t, steps: porTrilha.get(t.id) ?? [] }));
  return NextResponse.json({ ok: true, paths: trilhas });
}

export async function POST(request: Request) {
  if (!(await conferirDono())) return semPermissao();

  const body = (await request.json().catch(() => null)) as Record<string, unknown> | null;
  const title = texto(body?.title);
  if (!title) return NextResponse.json({ error: "A trilha precisa de um nome." }, { status: 400 });

  const slug = faxinarSlug(texto(body?.slug) || title);
  if (!slug) return NextResponse.json({ error: "Endereço inválido." }, { status: 400 });

  const admin = createAdminClient();
  const { data: ultima } = await admin
    .from("help_paths")
    .select("position")
    .order("position", { ascending: false })
    .limit(1)
    .maybeSingle();

  const { data, error } = await admin
    .from("help_paths")
    .insert({
      slug,
      title,
      description: texto(body?.description) || null,
      position: (ultima?.position ?? 0) + 1,
    })
    .select(CAMPOS_DA_TRILHA)
    .single();

  if (error) {
    const repetido = /duplicate key/i.test(error.message);
    return NextResponse.json(
      { error: repetido ? "Já existe uma trilha com esse endereço." : "Não foi possível criar a trilha." },
      { status: 400 }
    );
  }
  return NextResponse.json({ ok: true, path: data });
}

export async function PATCH(request: Request) {
  if (!(await conferirDono())) return semPermissao();

  const body = (await request.json().catch(() => null)) as Record<string, unknown> | null;
  const id = texto(body?.id);
  if (!id) return NextResponse.json({ error: "Sem trilha." }, { status: 400 });

  const admin = createAdminClient();

  /* Os passos chegam inteiros, na ordem final. Trocar dois de lugar mudaria a
     posição de todos entre eles, então mandar a lista toda é mais simples e
     mais seguro do que mandar os deltas. */
  if (Array.isArray(body?.steps)) {
    const ids = (body.steps as unknown[]).map((v) => texto(v)).filter(Boolean);
    await admin.from("help_path_steps").delete().eq("path_id", id);
    if (ids.length > 0) {
      const { error } = await admin
        .from("help_path_steps")
        .insert(ids.map((article_id, position) => ({ path_id: id, article_id, position })));
      if (error) return NextResponse.json({ error: "Não foi possível salvar os passos." }, { status: 400 });
    }
  }

  const mudanca: Record<string, unknown> = {};
  if (body?.title !== undefined) {
    const title = texto(body.title);
    if (!title) return NextResponse.json({ error: "A trilha precisa de um nome." }, { status: 400 });
    mudanca.title = title;
  }
  if (body?.slug !== undefined) {
    const slug = faxinarSlug(body.slug);
    if (!slug) return NextResponse.json({ error: "Endereço inválido." }, { status: 400 });
    mudanca.slug = slug;
  }
  if (body?.description !== undefined) mudanca.description = texto(body.description) || null;
  if (body?.active !== undefined) mudanca.active = Boolean(body.active);

  if (Object.keys(mudanca).length > 0) {
    const { error } = await admin.from("help_paths").update(mudanca).eq("id", id);
    if (error) return NextResponse.json({ error: "Não foi possível salvar a trilha." }, { status: 400 });
  }

  const { data } = await admin.from("help_paths").select(CAMPOS_DA_TRILHA).eq("id", id).maybeSingle();
  return NextResponse.json({ ok: true, path: data });
}

export async function DELETE(request: Request) {
  if (!(await conferirDono())) return semPermissao();

  const { searchParams } = new URL(request.url);
  const id = texto(searchParams.get("id"));
  if (!id) return NextResponse.json({ error: "Sem trilha." }, { status: 400 });

  const admin = createAdminClient();
  const { error } = await admin.from("help_paths").delete().eq("id", id);
  if (error) return NextResponse.json({ error: "Não foi possível apagar a trilha." }, { status: 400 });
  return NextResponse.json({ ok: true });
}
