// This module is only meant to be used in Server Components in the app/ directory
// It cannot be imported in Client Components or pages/ directory

import { redirect } from 'next/navigation';
import { CustomerResponse, CustomerStats } from './api-client';

// Dynamically import cookies to prevent build errors
let cookiesModule: any;
try {
  // This will only work in server components
  cookiesModule = require('next/headers');
} catch (error) {
  console.warn('Warning: next/headers only works in Server Components in the app/ directory');
}

/**
 * Constructs a server-side API URL for backend requests
 * Used in Server Components and API routes to directly access the backend API
 * 
 * @param endpoint The API endpoint path
 * @returns A complete URL to the backend API
 */
function getServerApiUrl(endpoint: string): string {
  const apiUrl = process.env.SERVER_API_URL || 'http://localhost:3001/api';

  // Validate API URL to prevent 500 errors
  if (!apiUrl || apiUrl === 'undefined' || apiUrl === 'null') {
    console.warn('SERVER_API_URL not properly set, using localhost fallback');
    const fallbackUrl = 'http://localhost:3001/api';
    const cleanEndpoint = endpoint.startsWith('/') ? endpoint.substring(1) : endpoint;
    return fallbackUrl.endsWith('/')
      ? `${fallbackUrl}${cleanEndpoint}`
      : `${fallbackUrl}/${cleanEndpoint}`;
  }

  const cleanEndpoint = endpoint.startsWith('/') ? endpoint.substring(1) : endpoint;

  return apiUrl.endsWith('/')
    ? `${apiUrl}${cleanEndpoint}`
    : `${apiUrl}/${cleanEndpoint}`;
}

/**
 * Server-side fetch wrapper with authentication.
 * Used in Server Components to make authenticated API requests to the backend.
 * This uses the SERVER_API_URL environment variable and is different from client-side fetching.
 * 
 * @throws Error if used outside of a Server Component in the app/ directory
 */
export async function fetchServer<T = unknown>(
  endpoint: string,
  options: RequestInit = {}
): Promise<T> {
  // Check if we're in a server component context
  if (!cookiesModule?.cookies) {
    throw new Error(
      "fetchServer can only be used in Server Components in the app/ directory. " +
      "For client components, use clientFetch or fetchClient instead."
    );
  }

  // Get auth token from cookies
  const cookieStore = await cookiesModule.cookies();
  const authToken = cookieStore.get('Authorization')?.value;

  // Redirect to login if not authenticated
  if (!authToken) redirect('/auth/login');

  try {
    // Get the complete backend URL using the utility function
    const url = getServerApiUrl(endpoint);

    // Make the request with proper auth headers
    const res = await fetch(url, {
      ...options,
      headers: {
        'Content-Type': 'application/json',
        Authorization: `Bearer ${authToken}`,
        ...options.headers,
      },
      cache: 'no-store', // Always fetch fresh data
    });

    // Handle auth failures
    if (res.status === 401) redirect('/auth/login');

    // Handle other errors
    if (!res.ok) {
      let errorData;
      try {
        errorData = await res.json();
      } catch {
        errorData = {};
      }

      // Handle new error format: { success: false, error: { message: "...", code: "..." } }
      // or old format: { error: "...", message: "..." }
      let errorMessage: string;
      if (errorData.error?.message) {
        errorMessage = errorData.error.message;
      } else if (typeof errorData.error === 'string') {
        errorMessage = errorData.error;
      } else if (errorData.message) {
        errorMessage = errorData.message;
      } else {
        errorMessage = `Request failed: ${res.status} ${res.statusText}`;
      }

      throw new Error(errorMessage);
    }

    // Handle 204 No Content responses
    if (res.status === 204) {
      return {} as T;
    }

    try {
      const data = await res.json();
      return data;
    } catch (parseError) {
      // If JSON parsing fails, throw a proper error
      throw new Error(`Failed to parse response from ${endpoint}: ${parseError instanceof Error ? parseError.message : String(parseError)}`);
    }
  } catch (error) {
    console.error(`Server request to ${endpoint} failed:`, error);
    // Ensure we always throw an Error instance, not an object
    if (error instanceof Error) {
      throw error;
    } else if (typeof error === 'string') {
      throw new Error(error);
    } else {
      const errorStr = error && typeof error === 'object' ? JSON.stringify(error) : String(error);
      throw new Error(`Request failed: ${errorStr}`);
    }
  }
}

/**
 * Get a paginated list of customers (server-side)
 * @param page Page number (starting from 1)
 * @param limit Number of items per page
 * @returns Promise with customers data and total count
 */
export const getCustomersServer = async (page: number = 1, limit: number = 25): Promise<CustomerResponse> => {
  return fetchServer(`/customers?page=${page}&limit=${limit}`);
};

/**
 * Get detailed stats for a specific customer (server-side)
 * @param userId The customer's user ID
 * @returns Promise with detailed customer stats
 */
export const getCustomerDetailsServer = async (userId: string): Promise<CustomerStats> => {
  return fetchServer(`/customers/${userId}`);
};

// Server-side platform stats function
export async function getPlatformStatsServer() {
  try {
    const url = getServerApiUrl('/stats/platform');

    // Make direct request without auth
    const res = await fetch(url, {
      cache: 'no-store',
      headers: {
        'Content-Type': 'application/json'
      }
    });

    const data = await res.json();

    // If we have real data, use it
    if (data && Object.keys(data).length > 0) {
      return data;
    }

    console.info('Using sample stats data for demo');
    return {
      orders: {
        completed: 1289
      },
      vendors: {
        total: 15
      },
      transactions: {
        volume: 38450,
        averageOrderValue: 29.83
      }
    };
  } catch (error) {
    console.error('Error fetching platform stats (server):', error);
    // Return default stats to prevent UI breakage
    return {
      orders: {
        completed: 0
      },
      vendors: {
        total: 0
      },
      transactions: {
        volume: 0,
        averageOrderValue: 0
      }
    };
  }
}

// Analytics Types for server-side
export interface AnalyticsOverview {
  orders: {
    total: number;
    completed: number;
    pending: number;
    completionRate: string;
  };
  revenue: {
    total: number;
    monthly: number;
    weekly: number;
    averageOrderValue: number;
  };
  products: {
    total: number;
  };
  customers: {
    unique: number;
  };
  userType?: 'vendor' | 'staff';
}

export interface RevenueData {
  _id: {
    year: number;
    month: number;
    day: number;
  };
  revenue: number;
  orders: number;
}

export interface ProductPerformance {
  productId: string;
  name: string;
  image: string;
  unitType: string;
  currentStock: number;
  stockStatus: string;
  totalSold: number;
  totalRevenue: number;
  orderCount: number;
  averagePrice: number;
}

export interface CustomerInsights {
  totalCustomers: number;
  segments: {
    new: number;
    returning: number;
    loyal: number;
    vip: number;
  };
  topCustomers: Array<{
    _id: string;
    orderCount: number;
    totalSpent: number;
    averageOrderValue: number;
    firstOrder: string;
    lastOrder: string;
  }>;
  averageOrdersPerCustomer: string;
}

export interface OrderAnalytics {
  statusDistribution: Array<{
    _id: string;
    count: number;
  }>;
  dailyOrders: Array<{
    _id: {
      year: number;
      month: number;
      day: number;
    };
    orders: number;
    revenue: number;
  }>;
  averageProcessingDays: number;
}

// Server-side analytics functions
export const getAnalyticsOverviewServer = async (storeId?: string): Promise<AnalyticsOverview> => {
  const url = storeId ? `/analytics/overview?storeId=${storeId}` : '/analytics/overview';
  return fetchServer<AnalyticsOverview>(url);
};

export const getRevenueTrendsServer = async (period: string = '30', storeId?: string): Promise<RevenueData[]> => {
  const params = new URLSearchParams({ period });
  if (storeId) params.append('storeId', storeId);

  const url = `/analytics/revenue-trends?${params.toString()}`;
  return fetchServer<RevenueData[]>(url);
};

export const getProductPerformanceServer = async (storeId?: string): Promise<ProductPerformance[]> => {
  const url = storeId ? `/analytics/product-performance?storeId=${storeId}` : '/analytics/product-performance';
  return fetchServer<ProductPerformance[]>(url);
};

export const getCustomerInsightsServer = async (storeId?: string): Promise<CustomerInsights> => {
  const url = storeId ? `/analytics/customer-insights?storeId=${storeId}` : '/analytics/customer-insights';
  return fetchServer<CustomerInsights>(url);
};

export const getOrderAnalyticsServer = async (period: string = '30', storeId?: string): Promise<OrderAnalytics> => {
  const params = new URLSearchParams({ period });
  if (storeId) params.append('storeId', storeId);

  const url = `/analytics/order-analytics?${params.toString()}`;
  return fetchServer<OrderAnalytics>(url);
}; 