import Constants from 'expo-constants';
import { Platform } from 'react-native';

const DEV_API_PORT = process.env.EXPO_PUBLIC_API_PORT || '8000';

/** Hostname the phone/emulator can use to reach your PC (from Metro / Expo Go). */
export function getDevMachineHost(): string | null {
  const debuggerHost = Constants.expoGoConfig?.debuggerHost;
  if (debuggerHost) {
    const host = debuggerHost.split(':')[0];
    if (host && host !== 'localhost' && host !== '127.0.0.1') {
      return host;
    }
  }

  const hostUri = Constants.expoConfig?.hostUri;
  const match = hostUri?.match(/(?:exp|http):\/\/([^:/]+)/);
  if (match?.[1] && match[1] !== 'localhost' && match[1] !== '127.0.0.1') {
    return match[1];
  }

  return null;
}

function isLocalOnlyHost(url: string): boolean {
  return /localhost|127\.0\.0\.1|\.localdev/i.test(url);
}

function rewriteHostname(url: string, hostname: string): string {
  try {
    const parsed = new URL(url);
    parsed.hostname = hostname;
    // clinic-frontend.localdev (Apache :80) often returns HTML on LAN IP — use artisan serve
    if (isLocalOnlyHost(url) && (!parsed.port || parsed.port === '80' || parsed.port === '')) {
      parsed.port = DEV_API_PORT;
    }
    return parsed.toString().replace(/\/$/, '');
  } catch {
    return `http://${hostname}:${DEV_API_PORT}/api`;
  }
}

/**
 * Resolves API base URL for the current device.
 * Prefer `php artisan serve --host=0.0.0.0 --port=8000` (see mobile-app README).
 */
export function getApiBaseUrl(): string {
  const fromEnv = process.env.EXPO_PUBLIC_API_URL?.trim();
  const devHost = getDevMachineHost();

  if (fromEnv) {
    if (isLocalOnlyHost(fromEnv)) {
      if (devHost) {
        return rewriteHostname(fromEnv, devHost);
      }
      if (Platform.OS === 'android') {
        return rewriteHostname(fromEnv, '10.0.2.2');
      }
    }
    return fromEnv;
  }

  if (devHost) {
    return `http://${devHost}:${DEV_API_PORT}/api`;
  }

  if (Platform.OS === 'android') {
    return `http://10.0.2.2:${DEV_API_PORT}/api`;
  }

  return `http://127.0.0.1:${DEV_API_PORT}/api`;
}

export function extractApiError(error: unknown): string {
  const err = error as {
    response?: { data?: { message?: string; errors?: Record<string, string[]> } };
    message?: string;
    code?: string;
  };

  if (err?.response?.data?.errors) {
    const messages = Object.values(err.response.data.errors).flat();
    if (messages[0]) return String(messages[0]);
  }

  if (err?.response?.data?.message) {
    return String(err.response.data.message);
  }

  return formatNetworkError(error);
}

export function formatNetworkError(error: unknown): string {
  const base = getApiBaseUrl();
  const err = error as { message?: string; code?: string };

  if (typeof err?.message === 'string' && err.message.trim().startsWith('<')) {
    return `API returned HTML instead of JSON at ${base}. Run: cd backend && php artisan serve --host=0.0.0.0 --port=8000`;
  }

  if (err?.message?.includes('Network Error') || err?.code === 'ERR_NETWORK') {
    return `Cannot reach API at ${base}. Start Laravel: php artisan serve --host=0.0.0.0 --port=8000 (same Wi‑Fi as phone).`;
  }

  return err?.message || 'Request failed.';
}
