function getApiBase(): string {
  return process.env.NEXT_PUBLIC_API_URL || 'https://deployhub-back.workzy.co';
}

function getToken(): string | null {
  if (typeof window === 'undefined') return null;
  return localStorage.getItem('deployhub_token');
}

export async function api<T>(
  path: string,
  options: RequestInit & { token?: string | null } = {},
): Promise<T> {
  const { token: optToken, ...init } = options;
  const token = optToken ?? getToken();
  const headers: HeadersInit = {
    ...(init.headers as Record<string, string>),
  };
  if (token) headers['Authorization'] = `Bearer ${token}`;
  const res = await fetch(`${getApiBase()}${path}`, { ...init, headers });
  if (!res.ok) {
    const text = await res.text();
    // Check for deactivated account error
    if (res.status === 401 && text.includes('deactivated')) {
      throw new Error('ACCOUNT_DEACTIVATED');
    }
    throw new Error(text || `HTTP ${res.status}`);
  }
  const contentType = res.headers.get('content-type');
  if (contentType?.includes('application/json')) return res.json();
  return res.text() as unknown as T;
}

/**
 * Upload a file to /api/builds/upload with progress reporting.
 * Progress increases gradually 0→100% over the whole operation (upload + server processing).
 */
export function uploadBuildWithProgress(
  file: File,
  onProgress: (percent: number) => void,
  releaseNotes?: string,
  password?: string,
): Promise<Build> {
  return new Promise((resolve, reject) => {
    const token = getToken();
    const xhr = new XMLHttpRequest();
    const form = new FormData();
    form.append('file', file);
    if (releaseNotes?.trim()) {
      form.append('releaseNotes', releaseNotes.trim());
    }
    if (password?.trim()) {
      form.append('password', password.trim());
    }

    let rampInterval: ReturnType<typeof setInterval> | null = null;
    const clearRamp = () => {
      if (rampInterval != null) {
        clearInterval(rampInterval);
        rampInterval = null;
      }
    };

    // 0–70% from upload progress
    xhr.upload.addEventListener('progress', (e) => {
      if (e.lengthComputable) {
        const uploadPercent = (e.loaded / e.total) * 100;
        const mapped = Math.round(uploadPercent * 0.7);
        const pct = Math.min(mapped, 70);
        onProgress(pct);
        if (pct >= 70 && !rampInterval) {
          let ramp = 70;
          rampInterval = setInterval(() => {
            ramp = Math.min(ramp + 2, 99);
            onProgress(ramp);
            if (ramp >= 99) clearRamp();
          }, 350);
        }
      }
    });

    xhr.addEventListener('load', () => {
      clearRamp();
      if (xhr.status >= 200 && xhr.status < 300) {
        onProgress(100);
        try {
          const json = JSON.parse(xhr.responseText);
          resolve(json);
        } catch {
          reject(new Error(xhr.responseText || 'Invalid response'));
        }
      } else {
        reject(new Error(xhr.responseText || `HTTP ${xhr.status}`));
      }
    });

    xhr.addEventListener('error', () => {
      clearRamp();
      reject(new Error('Network error'));
    });
    xhr.addEventListener('abort', () => {
      clearRamp();
      reject(new Error('Upload aborted'));
    });

    xhr.open('POST', `${getApiBase()}/api/builds/upload`);
    if (token) xhr.setRequestHeader('Authorization', `Bearer ${token}`);
    xhr.send(form);
  });
}

export function getAuthUrl(): string {
  return `${getApiBase()}/api/auth/google`;
}

export function setToken(token: string) {
  if (typeof window !== 'undefined') localStorage.setItem('deployhub_token', token);
}

export function clearToken() {
  if (typeof window !== 'undefined') localStorage.removeItem('deployhub_token');
}

export interface User {
  id: string;
  email: string;
  name: string;
  profilePhoto?: string;
  showUploaderInfo?: boolean;
  effectiveSettings?: {
    maxBuildSizeMb: number;
    cicdEnabled: boolean;
    slackEnabled: boolean;
  };
}

/** Update current user profile (e.g. name). Backend may support PATCH /api/users/me. */
export async function updateUser(updates: { name?: string; showUploaderInfo?: boolean }): Promise<User> {
  return api<User>('/api/users/me', {
    method: 'PATCH',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(updates),
  });
}

export interface Build {
  id: string;
  version: string;
  buildNumber: string;
  minOs: string | null;
  size: number;
  createdAt: string;
  shortCode?: string;
  /** Build type: For iOS (Development/AdHoc/Enterprise/AppStore), For Android (Debug/Release) */
  buildType?: string;
  /** iOS only: Provisioning profile type */
  provisioningProfile?: string;
  /** iOS only: UDIDs included in the build */
  udids?: string[];
  downloadCount?: number;
  updateDescription?: string;
  /** Whether this build is password protected */
  isPasswordProtected?: boolean;
  /** Plain text password (only visible to owner) */
  passwordText?: string | null;
}

export interface AppItem {
  id: string;
  platform: 'android' | 'ios';
  appName: string;
  bundleOrPackage: string;
  createdAt: string;
  /** App icon URL (extracted from the first uploaded build) */
  iconUrl?: string;
  builds: Build[];
}

export interface InstallInfo {
  platform: 'android' | 'ios';
  installUrl: string;
  appName?: string;
  version?: string;
  buildNumber?: string;
  size?: number;
  publishedAt?: string;
  shortCode?: string;
  /** Release notes / update description */
  updateDescription?: string;
  /** App icon URL (extracted from build) */
  iconUrl?: string;
  /** True when the file was removed from Drive or is no longer accessible */
  unavailable?: boolean;
  message?: string;
  /** Build type: For iOS (Development/AdHoc/Enterprise/AppStore), For Android (Debug/Release) */
  buildType?: string;
  /** iOS only: Provisioning profile type */
  provisioningProfile?: string;
  /** iOS only: UDIDs included in the build */
  udids?: string[];
  /** Whether this build is password protected */
  isPasswordProtected?: boolean;
  /** Uploader name (if enabled in settings) */
  uploaderName?: string;
}

export interface ApiKeyItem {
  id: string;
  name: string;
  keyPrefix: string;
  isActive: boolean;
  lastUsedAt: string | null;
  createdAt: string;
}

export interface ApiKeyCreateResponse extends ApiKeyItem {
  key: string;
  message: string;
}

export async function createApiKey(name: string): Promise<ApiKeyCreateResponse> {
  return api<ApiKeyCreateResponse>('/api/api-keys', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ name }),
  });
}

export async function listApiKeys(): Promise<ApiKeyItem[]> {
  return api<ApiKeyItem[]>('/api/api-keys');
}

export async function revokeApiKey(id: string): Promise<{ success: boolean }> {
  return api(`/api/api-keys/${encodeURIComponent(id)}/revoke`, { method: 'PATCH' });
}

export async function deleteApiKey(id: string): Promise<{ success: boolean }> {
  return api(`/api/api-keys/${encodeURIComponent(id)}`, { method: 'DELETE' });
}

export function deleteBuild(buildId: string): Promise<{ success: boolean }> {
  return api(`/api/builds/${encodeURIComponent(buildId)}`, { method: 'DELETE' });
}

/** Update build release notes / update description. Backend may support PATCH /api/builds/:id. */
export async function updateBuildReleaseNotes(buildId: string, updateDescription: string): Promise<Build> {
  return api<Build>(`/api/builds/${encodeURIComponent(buildId)}`, {
    method: 'PATCH',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ updateDescription }),
  });
}

/** Update build password */
export async function updateBuildPassword(buildId: string, password: string | null, removePassword: boolean = false): Promise<Build> {
  return api<Build>(`/api/builds/${encodeURIComponent(buildId)}`, {
    method: 'PATCH',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ password, removePassword }),
  });
}

export function deleteApp(appId: string): Promise<{ success: boolean }> {
  return api(`/api/apps/${encodeURIComponent(appId)}`, { method: 'DELETE' });
}

export async function getPublicSettings(userId?: string): Promise<{ buildLinkExpiryDays: number; aiReleaseNotesEnabled: boolean }> {
  const base = getApiBase();
  const params = userId ? `?userId=${encodeURIComponent(userId)}` : '';
  const res = await fetch(`${base}/api/install/public-settings${params}`);
  if (!res.ok) return { buildLinkExpiryDays: 0, aiReleaseNotesEnabled: true };
  return res.json();
}

export function isBuildExpired(createdAt: string, expiryDays: number): boolean {
  if (expiryDays <= 0) return false;
  const created = new Date(createdAt).getTime();
  const expiryMs = expiryDays * 24 * 60 * 60 * 1000;
  return Date.now() > created + expiryMs;
}

export function getInstallInfoUrl(buildId: string): string {
  return `${getApiBase()}/api/install/info?build_id=${encodeURIComponent(buildId)}`;
}

export function getApkDownloadUrl(buildIdOrShortCode: string): string {
  // If it looks like a short code (8 uppercase alphanumeric), use short code endpoint
  if (/^[A-Z0-9]{8}$/.test(buildIdOrShortCode)) {
    return `${getApiBase()}/api/install/download/${buildIdOrShortCode}`;
  }
  return `${getApiBase()}/api/install/download/${encodeURIComponent(buildIdOrShortCode)}`;
}

export function getRedirectUrl(buildId: string): string {
  return `${getApiBase()}/api/install/redirect?build_id=${encodeURIComponent(buildId)}`;
}

function getAppBase(): string {
  if (typeof window !== 'undefined') return window.location.origin;
  return process.env.NEXT_PUBLIC_APP_URL || 'https://deployhub.workzy.co';
}

export function getDownloadPageUrl(buildId: string): string {
  return `${getAppBase()}/download?build_id=${encodeURIComponent(buildId)}`;
}

export function getShortUrl(shortCode: string): string {
  return `${getAppBase()}/s/${shortCode}`;
}

/** Public endpoint – no auth required (for short link redirect). */
export async function getBuildIdFromShortCode(code: string): Promise<{ buildId: string }> {
  const base = getApiBase();
  const res = await fetch(`${base}/api/install/short/${encodeURIComponent(code)}`);
  if (!res.ok) throw new Error('Not found');
  return res.json();
}

/** Verify password for a password-protected build */
export async function verifyBuildPassword(buildId: string, password: string): Promise<boolean> {
  try {
    const base = getApiBase();
    const res = await fetch(`${base}/api/install/verify-password`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ buildId, password }),
    });
    return res.ok;
  } catch {
    return false;
  }
}
