import type { FastifyInstance } from "fastify";
import { z } from "zod";

import { AppError } from "../lib/errors.js";
import { supabaseAdmin } from "../lib/supabase.js";
import { isoNow, uniqueSlug } from "../lib/utils.js";
import { requireProfile, requireOrganizationMembership } from "../services/auth-service.js";

const createOrganizationSchema = z.object({
  name: z.string().min(2)
});

export function registerOrganizationRoutes(app: FastifyInstance) {
  app.get("/api/organizations", async (request) => {
    const { user } = await requireProfile(request);
    const { data, error } = await supabaseAdmin
      .from("organization_members")
      .select("role, organizations(id, name, slug)")
      .eq("auth_user_id", user.id);

    if (error) {
      throw new AppError(400, "ORGANIZATION_LIST_FAILED", error.message);
    }

    return {
      items: ((data ?? []) as Array<Record<string, any>>).map((entry) => ({
        role: entry.role,
        organization: Array.isArray(entry.organizations) ? entry.organizations[0] : entry.organizations
      }))
    };
  });

  app.post("/api/organizations", async (request) => {
    const { user } = await requireProfile(request);
    const payload = createOrganizationSchema.parse(request.body);

    const { data: organization, error } = await supabaseAdmin
      .from("organizations")
      .insert({
        name: payload.name,
        slug: uniqueSlug(payload.name)
      })
      .select("id, name, slug")
      .single();

    if (error || !organization) {
      throw new AppError(400, "ORGANIZATION_CREATE_FAILED", error?.message ?? "Unable to create organization.");
    }

    const { error: membershipError } = await supabaseAdmin.from("organization_members").insert({
      organization_id: organization.id,
      auth_user_id: user.id,
      role: "owner"
    });

    if (membershipError) {
      throw new AppError(400, "ORGANIZATION_CREATE_FAILED", membershipError.message);
    }

    const { data: freePlan } = await supabaseAdmin
      .from("plan_definitions")
      .select("id")
      .eq("code", "free")
      .single();

    if (freePlan?.id) {
      await supabaseAdmin.from("organization_subscriptions").insert({
        organization_id: organization.id,
        plan_definition_id: freePlan.id,
        status: "active"
      });
    }

    await supabaseAdmin.from("brand_kits").upsert(
      {
        organization_id: organization.id,
        primary_color: "#0f766e",
        secondary_color: "#0f172a",
        accent_color: "#14b8a6"
      },
      {
        onConflict: "organization_id"
      }
    );

    return {
      organization
    };
  });

  app.post("/api/organizations/:id/switch", async (request, reply) => {
    const params = z.object({ id: z.string().uuid() }).parse(request.params);
    const { profile } = await requireProfile(request);
    await requireOrganizationMembership(request, params.id);

    const { error } = await supabaseAdmin
      .from("user_profiles")
      .update({
        default_organization_id: params.id,
        updated_at: isoNow()
      })
      .eq("id", profile.id);

    if (error) {
      throw new AppError(400, "ORGANIZATION_SWITCH_FAILED", error.message);
    }

    reply.setCookie("na_active_org", params.id, {
      sameSite: "lax",
      path: "/",
      httpOnly: false,
      maxAge: 60 * 60 * 24 * 30
    });

    return {
      success: true
    };
  });
}
