import path from 'path';
import sharp from 'sharp';

import { listFlockNotes } from '../repositories/auditRepository.js';
import { getBirdById, listVetVisitsForBird, listWeightsForBird } from '../repositories/birdRepository.js';
import { getS3ImageStorageConfig } from '../storage/imageStorageConfig.js';
import { getSignedS3ObjectUrl } from '../storage/s3Client.js';
import type { BirdRow } from '../types.js';
import { renderAdoptionReportPdf } from './adoptionReport.js';

const adoptionReportWeightHistoryDays = 14;

const parseDataImage = (value: string | null) => {
  if (!value) {
    return null;
  }

  const match = value.match(/^data:image\/(?:png|jpeg|jpg|webp|gif);base64,(.+)$/);
  return match ? Buffer.from(match[1], 'base64') : null;
};

const normalizeReportPhotoBuffer = async (imageBuffer: Buffer | null) => {
  if (!imageBuffer) {
    return null;
  }

  try {
    return await sharp(imageBuffer).rotate().png().toBuffer();
  } catch (error) {
    console.warn('Unable to normalize bird photo for adoption report:', error);
    return null;
  }
};

const loadBirdReportPhotoBuffer = async (bird: BirdRow) => {
  if (!bird.photo_object_key) {
    return normalizeReportPhotoBuffer(parseDataImage(bird.photo_data_url));
  }

  const s3Config = getS3ImageStorageConfig();

  if (!s3Config) {
    return null;
  }

  const signedUrl = getSignedS3ObjectUrl({
    config: s3Config,
    objectKey: bird.photo_object_key,
    expiresInSeconds: 5 * 60,
  });
  const imageResponse = await fetch(signedUrl);

  if (!imageResponse.ok) {
    return null;
  }

  return normalizeReportPhotoBuffer(Buffer.from(await imageResponse.arrayBuffer()));
};

export const renderAdoptionReportForBird = async ({
  birdId,
  workspaceId,
  transferCode,
  printFriendly,
}: {
  birdId: string;
  workspaceId: number;
  transferCode: string;
  printFriendly: boolean;
}) => {
  const bird = await getBirdById(birdId, workspaceId);

  if (!bird) {
    throw new Error('Bird not found.');
  }

  const [weights, vetVisits, notes, birdPhotoBuffer] = await Promise.all([
    listWeightsForBird(bird.id, workspaceId, adoptionReportWeightHistoryDays),
    listVetVisitsForBird(bird.id, workspaceId),
    listFlockNotes(workspaceId),
    loadBirdReportPhotoBuffer(bird),
  ]);
  const birdNotes = notes.filter((note) => note.bird_id === bird.id);

  return renderAdoptionReportPdf({
    bird,
    weights,
    vetVisits,
    notes: birdNotes,
    transferCode,
    birdPhotoBuffer,
    printFriendly,
    assets: {
      logoPath: path.join(process.cwd(), 'assets', 'flockpal-logo.png'),
      wordmarkPath: path.join(process.cwd(), 'assets', 'flockpal-text.png'),
      defaultBirdPhotoPath: path.join(process.cwd(), 'assets', 'yoda-default.png'),
    },
  });
};
