import { createClient } from "https://esm.sh/@supabase/supabase-js@2.49.1";

const corsHeaders = {
  "Access-Control-Allow-Origin": "*",
  "Access-Control-Allow-Headers":
    "authorization, x-client-info, apikey, content-type, x-supabase-client-platform, x-supabase-client-platform-version, x-supabase-client-runtime, x-supabase-client-runtime-version",
};

function jsonResponse(payload: unknown, status = 200) {
  return new Response(JSON.stringify(payload), {
    status,
    headers: { ...corsHeaders, "Content-Type": "application/json" },
  });
}

function extractUserIdFromAuthHeader(authHeader: string | null) {
  if (!authHeader?.startsWith("Bearer ")) return null;

  try {
    const token = authHeader.replace("Bearer ", "");
    const payload = token.split(".")[1];
    if (!payload) return null;

    const normalized = payload.replace(/-/g, "+").replace(/_/g, "/");
    const padded = normalized.padEnd(Math.ceil(normalized.length / 4) * 4, "=");
    const decoded = JSON.parse(atob(padded));

    return typeof decoded?.sub === "string" ? decoded.sub : null;
  } catch (error) {
    console.error("sync-google-calendar token decode failed", error);
    return null;
  }
}

function mapGoogleCalendarError(error: any) {
  const reason = error?.details?.find?.((detail: any) => detail?.reason)?.reason
    ?? error?.errors?.[0]?.reason;
  const message = error?.message || "Google Calendar request failed.";

  if (reason === "ACCESS_TOKEN_SCOPE_INSUFFICIENT" || reason === "insufficientPermissions") {
    return {
      error: "Your Google connection needs to be refreshed for Calendar access. Disconnect Google and connect it again.",
      code: "RECONNECT_REQUIRED",
      reconnectRequired: true,
    };
  }

  if (reason === "SERVICE_DISABLED" || /calendar api has not been used|calendar api.*disabled/i.test(message)) {
    return {
      error: "Google Calendar API is not enabled in the connected Google project.",
      code: "API_DISABLED",
    };
  }

  return {
    error: message,
    code: "GOOGLE_API_ERROR",
  };
}

async function refreshAccessToken(serviceClient: any, userId: string, refreshToken: string, clientId: string, clientSecret: string) {
  const res = await fetch("https://oauth2.googleapis.com/token", {
    method: "POST",
    headers: { "Content-Type": "application/x-www-form-urlencoded" },
    body: new URLSearchParams({
      client_id: clientId,
      client_secret: clientSecret,
      refresh_token: refreshToken,
      grant_type: "refresh_token",
    }),
  });

  const data = await res.json();
  if (data.error) throw new Error(data.error_description || data.error);

  const expiresAt = new Date(Date.now() + data.expires_in * 1000).toISOString();
  await serviceClient
    .from("google_drive_tokens")
    .update({
      access_token: data.access_token,
      token_expires_at: expiresAt,
    })
    .eq("user_id", userId);

  return data.access_token;
}

Deno.serve(async (req) => {
  if (req.method === "OPTIONS") {
    return new Response(null, { headers: corsHeaders });
  }

  try {
    const GOOGLE_CLIENT_ID = Deno.env.get("GOOGLE_CLIENT_ID");
    const GOOGLE_CLIENT_SECRET = Deno.env.get("GOOGLE_CLIENT_SECRET");
    const SUPABASE_URL = Deno.env.get("SUPABASE_URL")!;
    const SERVICE_ROLE_KEY = Deno.env.get("SUPABASE_SERVICE_ROLE_KEY")!;

    if (!GOOGLE_CLIENT_ID || !GOOGLE_CLIENT_SECRET) {
      return jsonResponse({
        error: "Google Calendar integration is not configured on the server.",
        code: "MISSING_CREDENTIALS",
      });
    }

    const authHeader = req.headers.get("Authorization");
    const userId = extractUserIdFromAuthHeader(authHeader);
    if (!userId) {
      return jsonResponse({ error: "Unauthorized" }, 401);
    }

    const serviceClient = createClient(SUPABASE_URL, SERVICE_ROLE_KEY);

    const { data: roles } = await serviceClient
      .from("user_roles")
      .select("role")
      .eq("user_id", userId);

    const isAdmin = roles?.some((role: any) => role.role === "admin" || role.role === "manager");
    if (!isAdmin) {
      return jsonResponse({ error: "Only admins can sync Google Calendar" }, 403);
    }

    const { data: tokenRow } = await serviceClient
      .from("google_drive_tokens")
      .select("*")
      .eq("user_id", userId)
      .maybeSingle();

    if (!tokenRow) {
      return jsonResponse({
        error: "Google account not connected. Connect Google first.",
        code: "NOT_CONNECTED",
      });
    }

    let accessToken = tokenRow.access_token;
    const expiresAt = new Date(tokenRow.token_expires_at);
    if (expiresAt <= new Date()) {
      if (!tokenRow.refresh_token) {
        return jsonResponse({
          error: "Your Google connection expired. Disconnect Google and connect it again.",
          code: "RECONNECT_REQUIRED",
          reconnectRequired: true,
        });
      }

      try {
        accessToken = await refreshAccessToken(
          serviceClient,
          userId,
          tokenRow.refresh_token,
          GOOGLE_CLIENT_ID,
          GOOGLE_CLIENT_SECRET,
        );
      } catch (error: any) {
        return jsonResponse({
          error: "Your Google connection could not be refreshed. Disconnect Google and connect it again.",
          code: "RECONNECT_REQUIRED",
          reconnectRequired: true,
          details: error?.message,
        });
      }
    }

    const body = await req.json();
    const { action, calendarIds } = body;

    if (action === "list_calendars") {
      const calRes = await fetch("https://www.googleapis.com/calendar/v3/users/me/calendarList", {
        headers: { Authorization: `Bearer ${accessToken}` },
      });
      const calData = await calRes.json();

      if (calData.error) {
        return jsonResponse(mapGoogleCalendarError(calData.error));
      }

      return jsonResponse({ calendars: calData.items || [] });
    }

    if (action === "sync") {
      const { data: assocs } = await serviceClient
        .from("associations")
        .select("id")
        .eq("status", "active")
        .limit(1);

      if (!assocs?.length) {
        return jsonResponse({ error: "No active association found" }, 400);
      }

      const defaultAssocId = assocs[0].id;
      const calendarsToSync = calendarIds || ["primary"];

      const timeMin = new Date();
      timeMin.setMonth(timeMin.getMonth() - 1);
      const timeMax = new Date();
      timeMax.setMonth(timeMax.getMonth() + 6);

      const allEvents: any[] = [];

      for (const calId of calendarsToSync) {
        const params = new URLSearchParams({
          timeMin: timeMin.toISOString(),
          timeMax: timeMax.toISOString(),
          singleEvents: "true",
          orderBy: "startTime",
          maxResults: "250",
        });

        const evtRes = await fetch(
          `https://www.googleapis.com/calendar/v3/calendars/${encodeURIComponent(calId)}/events?${params}`,
          { headers: { Authorization: `Bearer ${accessToken}` } },
        );
        const evtData = await evtRes.json();

        if (evtData.error) {
          console.error(`Error fetching calendar ${calId}:`, evtData.error);
          return jsonResponse(mapGoogleCalendarError(evtData.error));
        }

        const events = (evtData.items || []).filter((event: any) => event.status !== "cancelled");
        for (const event of events) {
          const startDate = event.start?.dateTime || event.start?.date || null;
          const endDate = event.end?.dateTime || event.end?.date || null;
          if (!startDate) continue;

          allEvents.push({
            title: event.summary || "Untitled",
            description: event.description || null,
            start_date: startDate,
            end_date: endDate || startDate,
            location: event.location || null,
            event_type: "event",
            all_day: !event.start?.dateTime,
            association_id: defaultAssocId,
            created_by: userId,
            visibility: ["admin"],
            is_blocked: false,
          });
        }
      }

      if (allEvents.length > 0) {
        await serviceClient
          .from("calendar_events")
          .delete()
          .eq("created_by", userId)
          .eq("event_type", "google_sync");

        const rows = allEvents.map((event) => ({ ...event, event_type: "google_sync" }));
        const { error: insertError } = await serviceClient.from("calendar_events").insert(rows);

        if (insertError) {
          console.error("Insert error:", insertError);
          return jsonResponse({ error: `Failed to save events: ${insertError.message}` }, 500);
        }
      }

      return jsonResponse({ count: allEvents.length });
    }

    return jsonResponse({ error: "Unknown action" }, 400);
  } catch (err: any) {
    console.error("sync-google-calendar error:", err);
    return jsonResponse({ error: err.message }, 500);
  }
});
