import { serve } from "https://deno.land/std@0.203.0/http/server.ts";
import { createClient } from "https://esm.sh/@supabase/supabase-js@2";

// CORS: allow browser-based web clients (adjust origin in production)
// Permit headers the supabase-js client sends (e.g. `apikey`, `x-client-info`) so
// browser preflight requests succeed. Keep origin wide for dev; in production
// prefer echoing the request origin and enabling credentials only when needed.
const CORS_HEADERS: Record<string, string> = {
  "Access-Control-Allow-Origin": "*",
  "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
  "Access-Control-Allow-Headers": "Content-Type, Authorization, apikey, x-client-info, x-requested-with, Origin, Accept",
  "Access-Control-Max-Age": "3600",
};

const jsonResponse = (body: unknown, status = 200) =>
  new Response(JSON.stringify(body), {
    status,
    headers: { "Content-Type": "application/json", ...CORS_HEADERS },
  });

serve(async (req) => {
  // Handle CORS preflight quickly so browsers can call this function from localhost/dev
  if (req.method === "OPTIONS") {
    return new Response(null, { status: 204, headers: CORS_HEADERS });
  }
  const supabaseUrl = Deno.env.get("SUPABASE_URL") ?? "";
  const anonKey = Deno.env.get("SUPABASE_ANON_KEY") ?? "";
  const serviceKey = Deno.env.get("SUPABASE_SERVICE_ROLE_KEY") ?? "";
  if (!supabaseUrl || !anonKey || !serviceKey) {
    return jsonResponse({ error: "Missing env configuration" }, 500);
  }

  // Authenticate caller (must be admin)
  const authHeader = req.headers.get("Authorization") ?? "";
  const token = authHeader.replace("Bearer ", "").trim();
  if (!token) return jsonResponse({ error: "Missing access token" }, 401);

  const authClient = createClient(supabaseUrl, anonKey, {
    global: { headers: { Authorization: `Bearer ${token}` } },
  });

  const { data: authData, error: authError } = await authClient.auth.getUser();
  if (authError || !authData?.user) return jsonResponse({ error: "Unauthorized" }, 401);

  // Use service role client for privileged DB ops
  const adminClient = createClient(supabaseUrl, serviceKey);

  // Ensure caller is admin in profiles table
  const { data: profile, error: profileError } = await adminClient
    .from("profiles")
    .select("role")
    .eq("id", authData.user.id)
    .maybeSingle();
  const role = (profile?.role ?? "").toString().toLowerCase();
  if (profileError || role !== "admin") return jsonResponse({ error: "Forbidden" }, 403);

  // Route request
  const url = new URL(req.url);
  const id = url.pathname.split("/").pop();

  try {
    if (req.method === "GET") {
      if (id && id !== "teams") {
        const { data, error } = await adminClient
          .from("teams")
          .select('*, team_members(*)')
          .eq('id', id)
          .maybeSingle();
        if (error) return jsonResponse({ error: error.message }, 400);
        return jsonResponse({ team: data });
      }

      const { data, error } = await adminClient
        .from("teams")
        .select('*, team_members(*)')
        .order('name');
      if (error) return jsonResponse({ error: error.message }, 400);
      return jsonResponse({ teams: data });
    }

    if (req.method === "POST") {
      // Support both: standard POST-create and POST with an 'action' parameter
      const body = await req.json();
      const action = typeof body.action === 'string' ? body.action.toLowerCase() : 'create';

      // Create (default POST)
      if (action === 'create') {
        const name = typeof body.name === 'string' ? body.name : undefined;
        const leaderId = typeof body.leader_id === 'string' ? body.leader_id : undefined;
        const officeIds = Array.isArray(body.office_ids) ? (body.office_ids as string[]) : [];
        const members = Array.isArray(body.members) ? (body.members as string[]) : [];

        if (!name || !leaderId || officeIds.length === 0) {
          return jsonResponse({ error: 'Missing required fields' }, 400);
        }

        const { data: insertedTeam, error: insertError } = await adminClient
          .from('teams')
          .insert({ name, leader_id: leaderId, office_ids: officeIds })
          .select()
          .single();
        if (insertError) return jsonResponse({ error: insertError.message }, 400);

        if (members.length > 0) {
          const rows = members.map((u) => ({ team_id: (insertedTeam as any).id, user_id: u }));
          const { error } = await adminClient.from('team_members').insert(rows);
          if (error) return jsonResponse({ error: error.message }, 400);
        }

        return jsonResponse({ team: insertedTeam }, 201);
      }

      // Update (POST with action='update')
      if (action === 'update') {
        const teamId = typeof body.id === 'string' ? body.id : undefined;
        if (!teamId) return jsonResponse({ error: 'Missing team id' }, 400);
        const name = typeof body.name === 'string' ? body.name : undefined;
        const leaderId = typeof body.leader_id === 'string' ? body.leader_id : undefined;
        const officeIds = Array.isArray(body.office_ids) ? (body.office_ids as string[]) : [];
        const members = Array.isArray(body.members) ? (body.members as string[]) : [];

        const { error: upErr } = await adminClient
          .from('teams')
          .update({ name, leader_id: leaderId, office_ids: officeIds })
          .eq('id', teamId);
        if (upErr) return jsonResponse({ error: upErr.message }, 400);

        await adminClient.from('team_members').delete().eq('team_id', teamId);
        if (members.length > 0) {
          const rows = members.map((u) => ({ team_id: teamId, user_id: u }));
          const { error } = await adminClient.from('team_members').insert(rows);
          if (error) return jsonResponse({ error: error.message }, 400);
        }

        const { data: updated, error: fetchErr } = await adminClient.from('teams').select().eq('id', teamId).maybeSingle();
        if (fetchErr) return jsonResponse({ error: fetchErr.message }, 400);
        return jsonResponse({ team: updated });
      }

      // Delete (POST with action='delete')
      if (action === 'delete') {
        const teamId = typeof body.id === 'string' ? body.id : undefined;
        if (!teamId) return jsonResponse({ error: 'Missing team id' }, 400);
        await adminClient.from('team_members').delete().eq('team_id', teamId);
        const { error } = await adminClient.from('teams').delete().eq('id', teamId);
        if (error) return jsonResponse({ error: error.message }, 400);
        return jsonResponse({ ok: true });
      }

      return jsonResponse({ error: 'Unknown POST action' }, 400);
    }

    if (req.method === "PUT") {
      if (!id || id === "teams") return jsonResponse({ error: "Missing team id" }, 400);
      const body = await req.json();
      const name = body.name as string | undefined;
      const leaderId = body.leader_id as string | undefined;
      const officeIds = (body.office_ids as string[] | undefined) ?? [];
      const members = (body.members as string[] | undefined) ?? [];

      const { error: upErr } = await adminClient.from('teams').update({ name, leader_id: leaderId, office_ids: officeIds }).eq('id', id);
      if (upErr) return jsonResponse({ error: upErr.message }, 400);

      await adminClient.from('team_members').delete().eq('team_id', id);
      if (members.length > 0) {
        const rows = members.map((u) => ({ team_id: id, user_id: u }));
        const { error } = await adminClient.from('team_members').insert(rows);
        if (error) return jsonResponse({ error: error.message }, 400);
      }

      const { data: updated, error: fetchErr } = await adminClient.from('teams').select().eq('id', id).maybeSingle();
      if (fetchErr) return jsonResponse({ error: fetchErr.message }, 400);
      return jsonResponse({ team: updated });
    }

    if (req.method === "DELETE") {
      if (!id || id === "teams") return jsonResponse({ error: "Missing team id" }, 400);
      await adminClient.from('team_members').delete().eq('team_id', id);
      const { error } = await adminClient.from('teams').delete().eq('id', id);
      if (error) return jsonResponse({ error: error.message }, 400);
      return jsonResponse({ ok: true });
    }

    return jsonResponse({ error: "Method not allowed" }, 405);
  } catch (err) {
    return jsonResponse({ error: (err as Error).message }, 500);
  }
});