/**
 * Webshop Data API - Unified REST API for E-commerce Data Access
 *
 * Provides real-time access to customer, order, and product data from
 * connected webshops (Shopify, WooCommerce, ShopRenter) without storing
 * personal data locally (GDPR compliant).
 *
 * Related: Issue #48 - GDPR-compliant webshop sync refactoring
 *
 * Authentication: API Key (Bearer token)
 * Rate Limit: 100 requests/minute per API key
 *
 * Endpoints:
 * - GET /webshop-data-api/customers?store_id={uuid}&page=1&limit=25
 * - GET /webshop-data-api/customers/{id}?store_id={uuid}
 * - GET /webshop-data-api/orders?store_id={uuid}&status=completed&page=1
 * - GET /webshop-data-api/orders/{id}?store_id={uuid}
 * - GET /webshop-data-api/products?store_id={uuid}&page=1
 * - GET /webshop-data-api/products/{id}?store_id={uuid}
 */

import { createClient } from "https://esm.sh/@supabase/supabase-js@2.39.7";
import { wrapHandler } from "../_shared/error-handler.ts";
import {
  requireApiKey,
  createApiKeyErrorResponse,
  addRateLimitHeaders,
  extractApiKey,
} from "../_shared/api-key-auth.ts";
import { getAdapters } from "../_shared/platform-adapters.ts";

// Import platform-specific clients
import * as ShopifyClient from "../_shared/shopify-client.ts";
import * as WooCommerceClient from "../_shared/woocommerce-client.ts";
import * as ShopRenterClient from "../_shared/shoprenter-client.ts";

const FUNCTION_NAME = "webshop-data-api";

interface PaginationMeta {
  page: number;
  limit: number;
  total?: number;
  has_more?: boolean;
}

interface ApiResponse {
  success: boolean;
  platform: string;
  data: unknown;
  pagination?: PaginationMeta;
  fetched_at: string;
}

/**
 * Main handler function
 */
async function handler(req: Request): Promise<Response> {
  const supabaseUrl = Deno.env.get("SUPABASE_URL");
  const supabaseServiceKey = Deno.env.get("SUPABASE_SERVICE_ROLE_KEY");

  if (!supabaseUrl || !supabaseServiceKey) {
    return new Response(
      JSON.stringify({ error: "Server configuration error" }),
      { status: 500, headers: { "Content-Type": "application/json" } }
    );
  }

  const supabaseAdmin = createClient(supabaseUrl, supabaseServiceKey);

  // Only allow GET requests
  if (req.method !== "GET") {
    return new Response(
      JSON.stringify({ error: "Method not allowed" }),
      { status: 405, headers: { "Content-Type": "application/json" } }
    );
  }

  // Validate API key
  const apiKeyResult = await requireApiKey(req, supabaseAdmin, "webshop_data");
  if (!apiKeyResult.valid) {
    return createApiKeyErrorResponse(apiKeyResult);
  }

  const userId = apiKeyResult.userId!;
  const apiKey = extractApiKey(req)!;

  // Parse URL and query parameters
  const url = new URL(req.url);
  const pathParts = url.pathname.split("/").filter((p) => p);

  // Expected path: /webshop-data-api/{resource}/{id?}
  if (pathParts[0] !== "webshop-data-api") {
    return new Response(
      JSON.stringify({ error: "Invalid endpoint" }),
      { status: 404, headers: { "Content-Type": "application/json" } }
    );
  }

  const resource = pathParts[1]; // 'customers', 'orders', or 'products'
  const resourceId = pathParts[2]; // Optional ID

  // Get query parameters
  const storeId = url.searchParams.get("store_id");
  const page = parseInt(url.searchParams.get("page") || "1");
  const limit = parseInt(url.searchParams.get("limit") || "25");
  const status = url.searchParams.get("status"); // For orders

  // Validate required parameters
  if (!storeId) {
    return new Response(
      JSON.stringify({
        error: "Missing required parameter: store_id",
        code: "MISSING_STORE_ID",
      }),
      { status: 400, headers: { "Content-Type": "application/json" } }
    );
  }

  if (!["customers", "orders", "products"].includes(resource)) {
    return new Response(
      JSON.stringify({
        error: "Invalid resource. Must be customers, orders, or products",
        code: "INVALID_RESOURCE",
      }),
      { status: 400, headers: { "Content-Type": "application/json" } }
    );
  }

  // Validate pagination parameters
  if (page < 1 || limit < 1 || limit > 100) {
    return new Response(
      JSON.stringify({
        error: "Invalid pagination parameters. Page must be >= 1, limit must be 1-100",
        code: "INVALID_PAGINATION",
      }),
      { status: 400, headers: { "Content-Type": "application/json" } }
    );
  }

  // Fetch store and verify ownership (include sync config for access policies)
  const { data: store, error: storeError } = await supabaseAdmin
    .from("stores")
    .select(`
      *,
      store_sync_config (
        products_access_policy,
        customers_access_policy,
        orders_access_policy
      )
    `)
    .eq("id", storeId)
    .eq("user_id", userId)
    .eq("is_active", true)
    .single();

  if (storeError || !store) {
    return new Response(
      JSON.stringify({
        error: "Store not found or access denied",
        code: "STORE_NOT_FOUND",
      }),
      { status: 404, headers: { "Content-Type": "application/json" } }
    );
  }

  // Check data access policies from store_sync_config
  const syncConfig = store.store_sync_config?.[0] || {};
  const policyKey = `${resource.slice(0, -1)}s_access_policy`; // customers_access_policy, orders_access_policy, products_access_policy
  const policy = syncConfig[policyKey] || 'not_allowed';

  if (policy === 'not_allowed') {
    return new Response(
      JSON.stringify({
        error: `Access to ${resource} is not enabled for this store`,
        code: "ACCESS_DENIED",
        hint: "Enable access in store settings",
      }),
      { status: 403, headers: { "Content-Type": "application/json" } }
    );
  }

  // Fetch data based on resource and platform
  let responseData: ApiResponse;

  try {
    switch (store.platform_name.toLowerCase()) {
      case "shopify":
        responseData = await fetchShopifyData(
          store,
          resource,
          resourceId,
          page,
          limit,
          status
        );
        break;
      case "woocommerce":
        responseData = await fetchWooCommerceData(
          store,
          resource,
          resourceId,
          page,
          limit,
          status
        );
        break;
      case "shoprenter":
        responseData = await fetchShopRenterData(
          store,
          resource,
          resourceId,
          page,
          limit,
          status
        );
        break;
      default:
        return new Response(
          JSON.stringify({
            error: `Unsupported platform: ${store.platform_name}`,
            code: "UNSUPPORTED_PLATFORM",
          }),
          { status: 400, headers: { "Content-Type": "application/json" } }
        );
    }

    const response = new Response(JSON.stringify(responseData), {
      status: 200,
      headers: { "Content-Type": "application/json" },
    });

    // Add rate limit headers
    return addRateLimitHeaders(response, apiKey);
  } catch (error) {
    console.error(`Error fetching ${resource}:`, error);

    return new Response(
      JSON.stringify({
        error: error instanceof Error ? error.message : "Failed to fetch data",
        code: "FETCH_ERROR",
      }),
      { status: 500, headers: { "Content-Type": "application/json" } }
    );
  }
}

/**
 * Fetch data from Shopify
 */
async function fetchShopifyData(
  store: any,
  resource: string,
  resourceId: string | undefined,
  page: number,
  limit: number,
  status: string | null
): Promise<ApiResponse> {
  const adapters = getAdapters("shopify");

  if (resourceId) {
    // Fetch single item
    const itemId = parseInt(resourceId);
    let data;

    if (resource === "customers") {
      const response = await ShopifyClient.shopifyApiRequest(
        store.id,
        `/customers/${itemId}.json`
      );
      data = adapters.customer(response.customer);
    } else if (resource === "orders") {
      const response = await ShopifyClient.shopifyApiRequest(
        store.id,
        `/orders/${itemId}.json`
      );
      data = adapters.order(response.order);
    } else if (resource === "products") {
      const response = await ShopifyClient.shopifyApiRequest(
        store.id,
        `/products/${itemId}.json`
      );
      data = adapters.product(response.product);
    }

    return {
      success: true,
      platform: "shopify",
      data,
      fetched_at: new Date().toISOString(),
    };
  } else {
    // Fetch list
    const sinceId = page > 1 ? undefined : undefined; // Shopify uses since_id for pagination
    let data;
    let rawData;

    if (resource === "customers") {
      rawData = await ShopifyClient.fetchCustomers(store.id, limit, sinceId);
      data = rawData.map((item: any) => adapters.customer(item));
    } else if (resource === "orders") {
      let endpoint = `/orders.json?limit=${limit}&status=${status || "any"}`;
      const response = await ShopifyClient.shopifyApiRequest(store.id, endpoint);
      rawData = response.orders || [];
      data = rawData.map((item: any) => adapters.order(item));
    } else if (resource === "products") {
      rawData = await ShopifyClient.fetchProducts(store.id, limit, sinceId);
      data = rawData.map((item: any) => adapters.product(item));
    }

    return {
      success: true,
      platform: "shopify",
      data,
      pagination: {
        page,
        limit,
        has_more: (rawData?.length || 0) === limit,
      },
      fetched_at: new Date().toISOString(),
    };
  }
}

/**
 * Fetch data from WooCommerce
 */
async function fetchWooCommerceData(
  store: any,
  resource: string,
  resourceId: string | undefined,
  page: number,
  limit: number,
  status: string | null
): Promise<ApiResponse> {
  const adapters = getAdapters("woocommerce");

  if (resourceId) {
    // Fetch single item
    const itemId = parseInt(resourceId);
    let data;

    if (resource === "customers") {
      const rawData = await WooCommerceClient.fetchCustomer(store.id, itemId);
      data = adapters.customer(rawData);
    } else if (resource === "orders") {
      const rawData = await WooCommerceClient.fetchOrder(store.id, itemId);
      data = adapters.order(rawData);
    } else if (resource === "products") {
      const rawData = await WooCommerceClient.fetchProduct(store.id, itemId);
      data = adapters.product(rawData);
    }

    return {
      success: true,
      platform: "woocommerce",
      data,
      fetched_at: new Date().toISOString(),
    };
  } else {
    // Fetch list
    let data;
    let rawData;

    if (resource === "customers") {
      rawData = await WooCommerceClient.fetchCustomers(store.id, page, limit);
      data = rawData.map((item: any) => adapters.customer(item));
    } else if (resource === "orders") {
      rawData = await WooCommerceClient.fetchOrders(
        store.id,
        page,
        limit,
        status || undefined
      );
      data = rawData.map((item: any) => adapters.order(item));
    } else if (resource === "products") {
      rawData = await WooCommerceClient.fetchProducts(store.id, page, limit);
      data = rawData.map((item: any) => adapters.product(item));
    }

    return {
      success: true,
      platform: "woocommerce",
      data,
      pagination: {
        page,
        limit,
        has_more: (rawData?.length || 0) === limit,
      },
      fetched_at: new Date().toISOString(),
    };
  }
}

/**
 * Fetch data from ShopRenter
 */
async function fetchShopRenterData(
  store: any,
  resource: string,
  resourceId: string | undefined,
  page: number,
  limit: number,
  status: string | null
): Promise<ApiResponse> {
  const adapters = getAdapters("shoprenter");

  if (resourceId) {
    // Fetch single item - ShopRenter client doesn't have individual fetch methods
    // So we'll fetch the list and filter (or implement individual fetches)
    throw new Error("Single item fetch not yet implemented for ShopRenter");
  } else {
    // Fetch list
    let data;
    let rawData;

    // ShopRenter uses 0-based pagination, so convert from 1-based (page 1 -> 0, page 2 -> 1, etc.)
    const shopRenterPage = Math.max(0, page - 1);

    if (resource === "customers") {
      const response = await ShopRenterClient.fetchCustomers(store.id, shopRenterPage, limit);
      rawData = response.items || [];
      data = rawData.map((item: any) => adapters.customer(item));
    } else if (resource === "orders") {
      const response = await ShopRenterClient.fetchOrders(store.id, shopRenterPage, limit);
      rawData = response.items || [];
      data = rawData.map((item: any) => adapters.order(item));
    } else if (resource === "products") {
      const response = await ShopRenterClient.fetchProducts(store.id, shopRenterPage, limit);
      rawData = response.items || [];
      data = rawData.map((item: any) => adapters.product(item));
    }

    return {
      success: true,
      platform: "shoprenter",
      data,
      pagination: {
        page,
        limit,
        has_more: (rawData?.length || 0) === limit,
      },
      fetched_at: new Date().toISOString(),
    };
  }
}

// Wrap handler with error handling
Deno.serve(wrapHandler(FUNCTION_NAME, handler));
