import prisma from '../lib/prisma';
import { AppError } from '../lib/utils';

export const JOB_CONTEXT_KIND = 'JOB_CONTEXT' as const;

export interface JobContextMetadata {
  kind: typeof JOB_CONTEXT_KIND;
  jobId: string;
  title: string;
  category?: string | null;
  location: string;
  budget?: number | null;
  status: string;
}

function buildJobContextContent(metadata: JobContextMetadata) {
  const budget =
    metadata.budget != null && metadata.budget > 0
      ? `Budget: PHP ${metadata.budget}`
      : 'Budget: Negotiable';
  const category = metadata.category ? `${metadata.category} · ` : '';
  return `Job context — ${metadata.title} · ${category}${metadata.location} · ${budget}`;
}

export function isJobContextMetadata(value: unknown): value is JobContextMetadata {
  if (!value || typeof value !== 'object') return false;
  const record = value as Record<string, unknown>;
  return record.kind === JOB_CONTEXT_KIND && typeof record.jobId === 'string';
}

export async function ensureJobContextMessage(
  conversationId: string,
  jobId: string,
  senderUserId: string
) {
  const job = await prisma.job.findFirst({
    where: { id: jobId, deletedAt: null },
    include: { category: { select: { name: true } } },
  });
  if (!job) throw new AppError('Job not found', 404);

  const existingMessages = await prisma.message.findMany({
    where: { conversationId },
    select: { metadata: true },
  });

  const alreadySeeded = existingMessages.some((message) =>
    isJobContextMetadata(message.metadata)
  );
  if (alreadySeeded) return null;

  const metadata: JobContextMetadata = {
    kind: JOB_CONTEXT_KIND,
    jobId: job.id,
    title: job.title,
    category: job.category?.name ?? null,
    location: job.location,
    budget: job.budget != null ? Number(job.budget) : null,
    status: job.status,
  };

  const message = await prisma.message.create({
    data: {
      conversationId,
      senderId: senderUserId,
      content: buildJobContextContent(metadata),
      metadata,
    },
    include: {
      sender: { select: { id: true, firstName: true, lastName: true, avatarUrl: true } },
    },
  });

  await prisma.conversation.update({
    where: { id: conversationId },
    data: { updatedAt: new Date() },
  });

  return message;
}
