import { data } from "react-router";
import type { Route } from "./+types/api.sync.webhook.$provider";
import { getProvider } from "~/lib/sync/registry";
import { getConnectionByProviderUser, updateTokens } from "~/lib/sync/connections.server";
import { isAlreadyImported, recordImport } from "~/lib/sync/imports.server";
import { createActivity } from "~/lib/activities.server";

export async function action({ params, request }: Route.ActionArgs) {
  if (request.method !== "POST") {
    return data({ error: "Method not allowed" }, { status: 405 });
  }

  const provider = getProvider(params.provider);
  if (!provider) return data({ ok: true }); // Don't reveal provider existence

  const body = await request.json();

  // Verify webhook token
  const expectedToken = process.env[`${params.provider.toUpperCase()}_WEBHOOK_TOKEN`];
  if (expectedToken && (body as { webhook_token?: string }).webhook_token !== expectedToken) {
    return data({ ok: true }); // Invalid token — ignore silently
  }

  const event = provider.parseWebhook(body);
  if (!event) return data({ ok: true }); // Unrecognized event — ignore silently

  // Look up user by provider user ID
  const connection = await getConnectionByProviderUser(provider.id, event.providerUserId);
  if (!connection) return data({ ok: true }); // Unknown user — ignore

  // Check duplicate
  const alreadyImported = await isAlreadyImported(connection.userId, provider.id, event.workoutId);
  if (alreadyImported) return data({ ok: true });

  try {
    // Refresh token if expired
    let tokens = {
      accessToken: connection.accessToken,
      refreshToken: connection.refreshToken,
      expiresAt: connection.expiresAt,
    };
    if (new Date() >= tokens.expiresAt) {
      tokens = await provider.refreshToken(tokens.refreshToken);
      await updateTokens(connection.id, tokens);
    }

    // Download and convert (if file available)
    const workout = { id: event.workoutId, name: "", type: "", startedAt: "", duration: null, distance: null, fileUrl: event.fileUrl };
    let gpx: string | null = null;
    if (workout.fileUrl) {
      const fileBuffer = await provider.downloadFile(tokens, workout);
      gpx = await provider.convertToGpx(fileBuffer);
    }

    // Create activity
    const activityId = await createActivity(connection.userId, {
      name: `${provider.name} workout`,
      gpx: gpx ?? undefined,
    });

    await recordImport(connection.userId, provider.id, event.workoutId, activityId);
  } catch (e) {
    console.error(`Webhook import failed for ${provider.id}/${event.workoutId}:`, e);
  }

  // Always return 200 to acknowledge the webhook
  return data({ ok: true });
}
