import { getDb } from "../../../db";
import {
  applicationActivities,
  applicationDocuments,
  applications,
} from "../../../db/schema";
import { defaultDocuments, parseEmail } from "../../../lib/workflow";

type Submission = {
  name?: unknown;
  phone?: unknown;
  email?: unknown;
  city?: unknown;
  preferredContact?: unknown;
  job?: unknown;
  experienceCode?: unknown;
  experienceLabel?: unknown;
  professionalField?: unknown;
  educationCode?: unknown;
  educationLabel?: unknown;
  targetCode?: unknown;
  targetLabel?: unknown;
  missions?: unknown;
  language?: unknown;
  eligibility?: {
    score?: unknown;
    tone?: unknown;
    title?: unknown;
    summary?: unknown;
    recommendation?: unknown;
    strengths?: unknown;
    missing?: unknown;
  } | null;
};

function clean(value: unknown, max = 500) {
  return String(value ?? "").trim().slice(0, max);
}

function makeReference() {
  const year = new Date().getUTCFullYear();
  const token = crypto.randomUUID().replaceAll("-", "").slice(0, 8).toUpperCase();
  return `CP-${year}-${token}`;
}

export async function POST(request: Request) {
  try {
    const body = (await request.json()) as Submission;
    const required = {
      name: clean(body.name, 120),
      phone: clean(body.phone, 30),
      city: clean(body.city, 100),
      preferredContact: clean(body.preferredContact, 30),
      job: clean(body.job, 160),
      experienceCode: clean(body.experienceCode, 30),
      experienceLabel: clean(body.experienceLabel, 80),
      professionalField: clean(body.professionalField, 180),
      educationCode: clean(body.educationCode, 30),
      educationLabel: clean(body.educationLabel, 80),
      targetCode: clean(body.targetCode, 30),
      targetLabel: clean(body.targetLabel, 100),
      missions: clean(body.missions, 2500),
    };

    const missingField = Object.entries(required).find(([, value]) => !value)?.[0];
    const digits = required.phone.replace(/\D/g, "");
    if (missingField || digits.length < 9 || digits.length > 15) {
      return Response.json(
        { error: "المعلومات المطلوبة غير مكتملة أو رقم الهاتف غير صحيح." },
        { status: 400 },
      );
    }

    const eligibility = body.eligibility ?? null;
    const score = Math.min(100, Math.max(0, Number(eligibility?.score) || 0));
    const reference = makeReference();
    const db = getDb();
    const now = new Date().toISOString();
    const [application] = await db
      .insert(applications)
      .values({
        reference,
        fullName: required.name,
        phone: required.phone,
        email: parseEmail(body.email),
        city: required.city,
        preferredContact: required.preferredContact,
        job: required.job,
        experienceCode: required.experienceCode,
        experienceLabel: required.experienceLabel,
        professionalField: required.professionalField,
        educationCode: required.educationCode,
        educationLabel: required.educationLabel,
        targetCode: required.targetCode,
        targetLabel: required.targetLabel,
        missions: required.missions,
        language: clean(body.language, 5) || "ar",
        eligibilityScore: score,
        eligibilityTone: clean(eligibility?.tone, 20) || "start",
        eligibilityTitle: clean(eligibility?.title, 240),
        eligibilitySummary: clean(eligibility?.summary, 1200),
        eligibilityRecommendation: clean(eligibility?.recommendation, 600),
        eligibilityStrengths: JSON.stringify(
          Array.isArray(eligibility?.strengths)
            ? eligibility.strengths.map((item) => clean(item, 180)).slice(0, 8)
            : [],
        ),
        eligibilityMissing: JSON.stringify(
          Array.isArray(eligibility?.missing)
            ? eligibility.missing.map((item) => clean(item, 180)).slice(0, 8)
            : [],
        ),
        createdAt: now,
        updatedAt: now,
      })
      .returning();

    await db.insert(applicationDocuments).values(
      defaultDocuments.map(([code, label]) => ({
        applicationId: application.id,
        code,
        label,
      })),
    );
    await db.insert(applicationActivities).values({
      applicationId: application.id,
      type: "created",
      title: "تم استلام طلب الدراسة الأولية",
      detail: score
        ? `أُرفق تقرير المحاكي بنتيجة توجيهية ${score}%.`
        : "تم التسجيل بدون إكمال محاكي الأهلية.",
      actor: "النظام",
    });

    try {
      await fetch("https://formsubmit.co/ajax/competences.plus30@gmail.com", {
        method: "POST",
        headers: { "Content-Type": "application/json", Accept: "application/json" },
        body: JSON.stringify({
          _subject: `Nouvelle inscription ${reference} — ${required.name}`,
          _template: "table",
          _captcha: "false",
          reference,
          nom: required.name,
          telephone: required.phone,
          email: parseEmail(body.email) || "Non renseigné",
          ville: required.city,
          contact_prefere: required.preferredContact,
          fonction: required.job,
          experience: required.experienceLabel,
          domaine: required.professionalField,
          niveau: required.educationLabel,
          objectif: required.targetLabel,
          missions: required.missions,
          score_simulateur: score ? `${score}%` : "Non complété",
          recommandation: clean(eligibility?.recommendation, 600),
        }),
        signal: AbortSignal.timeout(4500),
      });
    } catch {
      // The application is already safely stored; email is only a notification.
    }

    return Response.json(
      {
        application: {
          reference: application.reference,
          status: application.status,
          emailLinked: Boolean(application.email),
        },
      },
      { status: 201 },
    );
  } catch (error) {
    const message = error instanceof Error ? error.message : "Unexpected error";
    return Response.json(
      {
        error: message.includes("no such table")
          ? "قاعدة بيانات التسجيلات غير جاهزة بعد. أعد المحاولة بعد لحظات."
          : "تعذر حفظ الطلب حالياً. حاول مرة أخرى.",
      },
      { status: 500 },
    );
  }
}
