/**
 * Staff Individual Application Management API
 * GET: Get application details - STAFF+
 * PATCH: Update application status - ADMIN+
 */

import { NextRequest, NextResponse } from "next/server";
import { getStaffSession } from "@/lib/staff-auth";
import { prisma } from "@/lib/db";
import { sendEmail } from "@/lib/email";
import { logger } from "@/lib/logger";

async function verifyStaffAuth(
  requiredRoles: string[] = ["STAFF", "ADMIN", "SUPER_ADMIN"],
) {
  const user = await getStaffSession();

  if (!user) {
    return {
      error: NextResponse.json({ error: "Unauthorized" }, { status: 401 }),
    };
  }

  if (!requiredRoles.includes(user.role)) {
    return {
      error: NextResponse.json(
        { error: "Insufficient permissions" },
        { status: 403 },
      ),
    };
  }

  return { user, role: user.role };
}

/**
 * GET /api/staff/applications/[id]
 * Fetch single application with full details
 */
export async function GET(
  request: NextRequest,
  { params }: { params: { id: string } },
) {
  const authResult = await verifyStaffAuth();
  if ("error" in authResult) return authResult.error;

  const { id } = params;

  try {
    const application = await prisma.job_applications.findUnique({
      where: { id },
      include: {
        jobs: {
          select: {
            id: true,
            slug: true,
            title_translations: true,
            department: true,
            department_label: true,
            location_translations: true,
            status: true,
          },
        },
      },
    });

    if (!application) {
      return NextResponse.json(
        { error: "Application not found" },
        { status: 404 },
      );
    }

    return NextResponse.json({ application });
  } catch (error) {
    logger.error("Staff application GET error", error);
    return NextResponse.json(
      { error: "Internal server error" },
      { status: 500 },
    );
  }
}

/**
 * PATCH /api/staff/applications/[id]
 * Update application status - ADMIN+ only
 */
export async function PATCH(
  request: NextRequest,
  { params }: { params: { id: string } },
) {
  const authResult = await verifyStaffAuth(["ADMIN", "SUPER_ADMIN"]);
  if ("error" in authResult) return authResult.error;

  const { id } = params;

  try {
    const body = await request.json();
    const {
      status,
      interviewLink,
      interviewScheduledAt,
      rejectionReason,
      internalNotes,
    } = body;

    // Validate status
    const validStatuses = [
      "new",
      "shortlisted",
      "interview_scheduled",
      "hired",
      "rejected",
    ];
    if (status && !validStatuses.includes(status)) {
      return NextResponse.json(
        {
          error: `Invalid status. Must be one of: ${validStatuses.join(", ")}`,
        },
        { status: 400 },
      );
    }

    // Get current application for email notification
    const currentApp = await prisma.job_applications.findUnique({
      where: { id },
      include: {
        jobs: {
          select: {
            title_translations: true,
          },
        },
      },
    });

    if (!currentApp) {
      return NextResponse.json(
        { error: "Application not found" },
        { status: 404 },
      );
    }

    // Build update object
    const updateData: Record<string, unknown> = {
      reviewed_by: authResult.user.id || authResult.user.email,
      reviewed_at: new Date().toISOString(),
    };

    if (status) updateData.status = status;
    if (interviewLink) updateData.interview_link = interviewLink;
    if (interviewScheduledAt)
      updateData.interview_scheduled_at = interviewScheduledAt;
    if (rejectionReason) updateData.rejection_reason = rejectionReason;
    if (internalNotes !== undefined) updateData.internal_notes = internalNotes;

    // Set hired_at timestamp when status changes to hired
    if (status === "hired") {
      updateData.hired_at = new Date().toISOString();
    }

    // Update application
    const updatedApp = await prisma.job_applications.update({
      where: { id },
      data: updateData,
      include: {
        jobs: {
          select: {
            title_translations: true,
          },
        },
      },
    });

    // Send email notification if status changed
    if (status && status !== currentApp.status) {
      await sendApplicationStatusEmail(updatedApp, status);
    }

    logger.info("Application status updated", {
      applicationId: id,
      oldStatus: currentApp.status,
      newStatus: status,
      updatedBy: authResult.user.email,
    });

    return NextResponse.json({ application: updatedApp });
  } catch (error) {
    logger.error("Staff application PATCH error", error);
    return NextResponse.json(
      { error: "Internal server error" },
      { status: 500 },
    );
  }
}

/**
 * Send email notification when application status changes
 */
// eslint-disable-next-line @typescript-eslint/no-explicit-any
async function sendApplicationStatusEmail(application: any, newStatus: string) {
  try {
    const lang = application.submission_language || "en";
    const isAr = lang === "ar";
    const jobTitle = application.jobs?.title_translations?.[lang] || "Position";
    const applicantName = application.applicant_name;
    const applicantEmail = application.applicant_email;

    let subject = "";
    let htmlContent = "";
    let textContent = "";

    switch (newStatus) {
      case "shortlisted":
        subject = isAr
          ? `تم اختيارك للمرحلة التالية - ${jobTitle}`
          : `Application Shortlisted - ${jobTitle}`;
        htmlContent = isAr
          ? `
            <h2>مبروك ${applicantName}!</h2>
            <p>يسعدنا إخبارك بأنه تم اختيارك للمرحلة التالية لوظيفة <strong>${jobTitle}</strong>.</p>
            <p>سيتواصل معك فريقنا قريباً لتحديد موعد المقابلة.</p>
            <p>مع أطيب التحيات،<br/>فريق التوظيف - ماويدي</p>
          `
          : `
            <h2>Congratulations ${applicantName}!</h2>
            <p>We're pleased to inform you that your application for <strong>${jobTitle}</strong> has been shortlisted.</p>
            <p>Our team will contact you shortly to schedule an interview.</p>
            <p>Best regards,<br/>Mawidi Hiring Team</p>
          `;
        break;

      case "interview_scheduled":
        const interviewLink = application.interview_link || "#";
        const interviewDate = application.interview_scheduled_at
          ? new Date(application.interview_scheduled_at).toLocaleDateString(
              isAr ? "ar-SA" : "en-US",
              {
                year: "numeric",
                month: "long",
                day: "numeric",
                hour: "2-digit",
                minute: "2-digit",
              },
            )
          : "TBD";

        subject = isAr
          ? `دعوة للمقابلة - ${jobTitle}`
          : `Interview Invitation - ${jobTitle}`;
        htmlContent = isAr
          ? `
            <h2>مرحباً ${applicantName}!</h2>
            <p>يسرنا دعوتك لإجراء مقابلة لوظيفة <strong>${jobTitle}</strong>.</p>
            ${application.interview_scheduled_at ? `<p><strong>موعد المقابلة:</strong> ${interviewDate}</p>` : ""}
            <p><strong>رابط المقابلة:</strong><br/><a href="${interviewLink}" style="color: #10B981; font-weight: bold;">${interviewLink}</a></p>
            <p>يرجى الاستعداد للمقابلة والانضمام في الوقت المحدد.</p>
            <p>نتطلع للقائك!<br/>فريق التوظيف - ماويدي</p>
          `
          : `
            <h2>Hello ${applicantName}!</h2>
            <p>We're excited to invite you for an interview for the <strong>${jobTitle}</strong> position.</p>
            ${application.interview_scheduled_at ? `<p><strong>Interview Date:</strong> ${interviewDate}</p>` : ""}
            <p><strong>Interview Link:</strong><br/><a href="${interviewLink}" style="color: #10B981; font-weight: bold;">${interviewLink}</a></p>
            <p>Please prepare for the interview and join at the scheduled time.</p>
            <p>Looking forward to meeting you!<br/>Mawidi Hiring Team</p>
          `;
        break;

      case "hired":
        subject = isAr ? `عرض عمل - ${jobTitle}` : `Job Offer - ${jobTitle}`;
        htmlContent = isAr
          ? `
            <h2>مبروك ${applicantName}!</h2>
            <p>يسعدنا أن نقدم لك عرض عمل رسمي لوظيفة <strong>${jobTitle}</strong> في ماويدي!</p>
            <p>سيتواصل معك فريق الموارد البشرية خلال الأيام القادمة لإتمام الإجراءات.</p>
            <p>نرحب بك في فريق ماويدي!</p>
            <p>مع أطيب التحيات،<br/>فريق الموارد البشرية - ماويدي</p>
          `
          : `
            <h2>Congratulations ${applicantName}!</h2>
            <p>We're thrilled to extend a formal job offer for the <strong>${jobTitle}</strong> position at Mawidi!</p>
            <p>Our HR team will contact you in the coming days to complete the onboarding process.</p>
            <p>Welcome to the Mawidi team!</p>
            <p>Best regards,<br/>Mawidi HR Team</p>
          `;
        break;

      case "rejected":
        subject = isAr
          ? `تحديث على طلب التوظيف - ${jobTitle}`
          : `Application Update - ${jobTitle}`;
        htmlContent = isAr
          ? `
            <h2>عزيزي ${applicantName},</h2>
            <p>شكراً لك على اهتمامك بوظيفة <strong>${jobTitle}</strong> في ماويدي.</p>
            <p>بعد المراجعة الدقيقة، قررنا المضي قدماً مع مرشحين آخرين في هذا الوقت.</p>
            <p>نقدر الوقت والجهد الذي بذلته في عملية التقديم، ونشجعك على التقديم على فرص مستقبلية تتناسب مع مؤهلاتك.</p>
            <p>نتمنى لك كل التوفيق في مسيرتك المهنية.</p>
            <p>مع أطيب التحيات،<br/>فريق التوظيف - ماويدي</p>
          `
          : `
            <h2>Dear ${applicantName},</h2>
            <p>Thank you for your interest in the <strong>${jobTitle}</strong> position at Mawidi.</p>
            <p>After careful consideration, we've decided to move forward with other candidates at this time.</p>
            <p>We appreciate the time and effort you invested in the application process, and we encourage you to apply for future opportunities that match your qualifications.</p>
            <p>We wish you the very best in your career journey.</p>
            <p>Best regards,<br/>Mawidi Hiring Team</p>
          `;
        break;

      default:
        return; // No email for 'new' status
    }

    textContent = htmlContent
      .replace(/<[^>]*>/g, "")
      .replace(/\s+/g, " ")
      .trim();

    await sendEmail(applicantEmail, {
      subject,
      html: htmlContent,
      text: textContent,
    });

    logger.info("Status change email sent", {
      to: applicantEmail,
      status: newStatus,
      jobTitle,
    });
  } catch (error) {
    logger.error("Failed to send status email", error);
    // Don't fail the request if email fails - log and continue
  }
}
