import { cache } from 'react';
import { and, eq } from 'drizzle-orm';

import { db } from '@/lib/db';
import { files } from '@/lib/db/schema/documents';
import { systemSettings } from '@/lib/db/schema/system';
import { getStorageBackend } from '@/lib/storage';
import { logger } from '@/lib/logger';

export const PORT_LOGO_SETTING_KEY = 'port_logo_file_id';

export type ResolvedLogo =
  | { source: 'logo'; buffer: Buffer; mimeType: 'image/png' }
  | { source: 'fallback'; buffer: null; mimeType: null };

async function readLogoSetting(portId: string): Promise<string | null> {
  const [row] = await db
    .select()
    .from(systemSettings)
    .where(and(eq(systemSettings.key, PORT_LOGO_SETTING_KEY), eq(systemSettings.portId, portId)));
  if (!row) return null;
  const value = row.value;
  if (typeof value !== 'string') return null;
  return value;
}

/**
 * Resolves the port-level logo for PDF rendering. Returns `source: 'fallback'`
 * when the setting is unset, the file row is missing, or the storage backend
 * errors. Renderers should fall back to text-only headers in that case.
 *
 * Cached per request via React `cache()` so multi-page PDFs only fetch once.
 */
export const resolvePortLogo = cache(async (portId: string): Promise<ResolvedLogo> => {
  const fileId = await readLogoSetting(portId);
  if (!fileId) {
    return { source: 'fallback', buffer: null, mimeType: null };
  }
  const file = await db.query.files.findFirst({ where: eq(files.id, fileId) });
  if (!file) {
    logger.warn({ portId, fileId }, 'port_logo_file_id points at missing file');
    return { source: 'fallback', buffer: null, mimeType: null };
  }
  try {
    const backend = await getStorageBackend();
    const stream = await backend.get(file.storagePath);
    const chunks: Buffer[] = [];
    for await (const chunk of stream) {
      chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
    }
    const buffer = Buffer.concat(chunks);
    return { source: 'logo', buffer, mimeType: 'image/png' };
  } catch (err) {
    logger.warn({ err, portId, fileId, storagePath: file.storagePath }, 'logo fetch failed');
    return { source: 'fallback', buffer: null, mimeType: null };
  }
});
