import {
  createAiModelGeneration,
  updateAiModelGeneration,
  createAiModelPhoto,
  createAiModelJob,
  updateAiModelJob,
  getAiModelJob,
  getPendingAiModelJobs,
} from './db.mjs';
import { generateAiModelPhotos } from './ai-model-photos.mjs';

let processing = false;
let loopStarted = false;
let loopTimer = null;

async function processOneJob(job) {
  let lastProgress = -1;
  let lastMessage = '';
  const reportProgress = (progress, message = '') => {
    const normalized = Math.max(1, Math.min(99, Math.round(Number(progress || 0))));
    const cleanMessage = String(message || '').trim();
    if (normalized === lastProgress && cleanMessage === lastMessage) return;
    lastProgress = normalized;
    lastMessage = cleanMessage;
    updateAiModelJob(job.id, {
      status: 'running',
      progress: normalized,
      progress_message: cleanMessage || 'AI-Bild wird erzeugt …',
      error_message: null,
    });
  };

  reportProgress(4, 'Job wird vorbereitet …');
  try {
    const payload = job.payload_json || {};
    const result = await generateAiModelPhotos({ ...payload, settings: payload.settings || {} }, reportProgress);
    reportProgress(94, 'Ergebnis wird gespeichert …');
    const generation = createAiModelGeneration({
      listing_id: payload.listing_id || null,
      context: payload.listing_id ? 'listing' : 'generator',
      mode: payload.mode || result.mode || 'flatlay',
      preset: result.precheck.preset,
      variants: result.photos.length,
      source_photos: Array.isArray(payload.photos) ? payload.photos : [],
      generated_photos: result.photos.map(photo => photo.filename),
      prompt_summary: result.prompt_summary,
      provider: result.provider?.provider || null,
      provider_model: result.provider?.model || null,
      moderation_notes: result.photos.map(photo => photo.moderation?.notes).filter(Boolean).join(' | ') || null,
      safety_status: 'safe',
      status: 'completed',
    });
    const photos = result.photos.map(photo => createAiModelPhoto({
      generation_id: generation.id,
      listing_id: payload.listing_id || null,
      variant_index: photo.variant_index,
      mode: photo.mode || payload.mode || 'flatlay',
      preset: photo.preset,
      image_path: photo.filename,
      source_photo: photo.source_photo,
      prompt: photo.prompt,
      provider: photo.provider || result.provider?.provider || null,
      provider_model: photo.provider_model || result.provider?.model || null,
      moderation_result: JSON.stringify(photo.moderation || {}),
      safety_status: photo.moderation?.safe === false ? 'blocked' : 'safe',
    }));
    updateAiModelGeneration(generation.id, {
      generated_photos: photos.map(photo => photo.image_path),
      provider: result.provider?.provider || null,
      provider_model: result.provider?.model || null,
      mode: payload.mode || result.mode || 'flatlay',
    });
    updateAiModelJob(job.id, {
      status: 'completed',
      progress: 100,
      progress_message: 'AI-Bilder sind fertig.',
      generation_id: generation.id,
    });
    return { generation, photos, provider: result.provider || null };
  } catch (err) {
    updateAiModelJob(job.id, {
      status: 'failed',
      progress: 100,
      progress_message: 'AI-Bildgenerierung fehlgeschlagen.',
      error_message: err.message || 'Unbekannter Fehler',
    });
    throw err;
  }
}
async function processQueue() {
  if (processing) return;
  processing = true;
  try {
    const pending = getPendingAiModelJobs(5);
    for (const job of pending) {
      try {
        await processOneJob(job);
      } catch {}
    }
  } finally {
    processing = false;
  }
}

export function startAiModelJobLoop() {
  if (loopStarted) return;
  loopStarted = true;
  loopTimer = setInterval(() => { processQueue().catch(() => {}); }, 2500);
  loopTimer.unref?.();
}

export function stopAiModelJobLoop() {
  if (loopTimer) clearInterval(loopTimer);
  loopTimer = null;
  loopStarted = false;
}

export function enqueueAiModelJob(payload = {}) {
  const job = createAiModelJob({
    listing_id: payload.listing_id || null,
    context: payload.listing_id ? 'listing' : 'generator',
    mode: payload.mode || 'model',
    preset: payload.preset || 'mixed',
    variants: payload.variants || 1,
    status: 'queued',
    progress: 0,
    payload_json: payload,
  });
  processQueue().catch(() => {});
  return job;
}

export function getAiModelJobWithRelations(id) {
  return getAiModelJob(id);
}
