import { query } from "../_generated/server";
import { v } from "convex/values";

/**
 * Get all published jobs (optionally filtered by department)
 * Phase 8: Content, Careers, Real Estate, Analytics, Reviews
 */
export const getJobs = query({
  args: {
    status: v.optional(v.string()),
    department: v.optional(v.string()),
  },
  handler: async (ctx, args) => {
    const status = args.status ?? "OPEN";
    const q = ctx.db
      .query("jobs")
      .withIndex("by_status", (q) => q.eq("status", status as any));

    if (args.department) {
      return await q
        .filter((f) => f.eq(f.field("department"), args.department))
        .collect();
    }

    return await q.collect();
  },
});

/**
 * Get job applications (staff view, paginated)
 * Phase 8: Content, Careers, Real Estate, Analytics, Reviews
 */
export const getApplications = query({
  args: {
    jobId: v.optional(v.string()),
    status: v.optional(v.string()),
    limit: v.optional(v.number()),
  },
  handler: async (ctx, args) => {
    const limit = args.limit ?? 50;
    let q: any = ctx.db.query("job_applications");

    if (args.jobId) {
      q = q.withIndex("by_jobId", (qb: any) => qb.eq("jobId", args.jobId));
    }

    return await q.order("desc").take(limit);
  },
});

/**
 * Get a single application by ID with job enrichment
 * Phase 8 + WU-14: Staff application management
 */
export const getApplicationById = query({
  args: { applicationId: v.string() },
  handler: async (ctx, args) => {
    // Try prismaId first
    let app = await ctx.db
      .query("job_applications")
      .filter((q) => q.eq(q.field("prismaId"), args.applicationId))
      .first();

    if (!app) {
      // Fallback: try as Convex _id
      try {
        app = (await ctx.db.get(args.applicationId as any)) as typeof app;
      } catch {
        return null;
      }
    }
    if (!app) return null;

    // Enrich with job data if jobId exists
    let job = null;
    if (app.jobId) {
      job = await ctx.db
        .query("jobs")
        .filter((q) => q.eq(q.field("prismaId"), app!.jobId!))
        .first();

      if (!job) {
        try {
          job = await ctx.db.get(app.jobId as any);
        } catch {
          // ignore
        }
      }
    }

    return { ...app, job };
  },
});

/**
 * Get interview bookings (optionally for a specific application)
 * Phase 8: Content, Careers, Real Estate, Analytics, Reviews
 */
export const getInterviewBookings = query({
  args: {
    applicationId: v.optional(v.string()),
    status: v.optional(v.string()),
    limit: v.optional(v.number()),
  },
  handler: async (ctx, args) => {
    const limit = args.limit ?? 20;
    let q: any = ctx.db.query("interview_bookings");

    if (args.applicationId) {
      q = q.withIndex("by_applicationId", (qb: any) =>
        qb.eq("applicationId", args.applicationId),
      );
    }

    return await q.order("desc").take(limit);
  },
});

// ── WU-14 gap-fill queries ──────────────────────────────────────────────

/**
 * Get a single interview booking by ID (prismaId or _id)
 * WU-14: Staff interview detail data-source routing
 */
export const getInterviewBookingById = query({
  args: { bookingId: v.string() },
  handler: async (ctx, args) => {
    // Try prismaId first
    const byPrisma = await ctx.db
      .query("interview_bookings")
      .filter((q) => q.eq(q.field("prismaId"), args.bookingId))
      .first();
    if (byPrisma) return byPrisma;

    // Try _id
    try {
      return (await ctx.db.get(args.bookingId as any)) as typeof byPrisma;
    } catch {
      return null;
    }
  },
});

/**
 * Validate an interview booking token by its token string.
 * Returns the token record plus associated application and job data.
 * Gap-fill for WU-05 data-source routing
 */
export const validateInterviewToken = query({
  args: {
    token: v.string(),
  },
  handler: async (ctx, args) => {
    const tokenDoc = await ctx.db
      .query("interview_booking_tokens")
      .withIndex("by_token", (q) => q.eq("token", args.token))
      .first();

    if (!tokenDoc) {
      return { valid: false, errorCode: "NOT_FOUND", error: "Token not found" };
    }

    if (tokenDoc.isRevoked) {
      return {
        valid: false,
        errorCode: "REVOKED",
        error: "Token has been revoked",
      };
    }

    if (tokenDoc.usedAt) {
      return {
        valid: false,
        errorCode: "USED",
        error: "Token has already been used",
      };
    }

    const now = Date.now();
    if (tokenDoc.expiresAt < now) {
      return { valid: false, errorCode: "EXPIRED", error: "Token has expired" };
    }

    // Fetch associated application
    const application = await ctx.db
      .query("job_applications")
      .filter((f) =>
        f.or(
          f.eq(f.field("prismaId"), tokenDoc.applicationId),
          f.eq(f.field("_id"), tokenDoc.applicationId as any),
        ),
      )
      .first();

    // Fetch associated job
    let job = null;
    if (tokenDoc.jobId) {
      job = await ctx.db
        .query("jobs")
        .filter((f) =>
          f.or(
            f.eq(f.field("prismaId"), tokenDoc.jobId),
            f.eq(f.field("_id"), tokenDoc.jobId as any),
          ),
        )
        .first();
    }

    return {
      valid: true,
      tokenRecord: {
        id: tokenDoc._id,
        token: tokenDoc.token,
        expiresAt: tokenDoc.expiresAt,
        usedAt: tokenDoc.usedAt ?? null,
        isRevoked: tokenDoc.isRevoked,
      },
      payload: {
        applicationId: tokenDoc.applicationId,
        jobId: tokenDoc.jobId ?? null,
      },
      application: application
        ? {
            id: application._id,
            applicantName: application.applicantName,
            applicantEmail: application.applicantEmail,
            applicantPhone: application.applicantPhone,
            status: application.status ?? "NEW",
          }
        : null,
      job: job
        ? {
            id: job._id,
            title: (job.titleTranslations as any)?.en ?? "",
            titleAr: (job.titleTranslations as any)?.ar ?? "",
            department: job.department,
            departmentAr: (job.departmentLabel as any)?.ar ?? "",
            location: (job.locationTranslations as any)?.en ?? "",
            locationAr: (job.locationTranslations as any)?.ar ?? "",
            employmentType: job.contractType,
            description: "",
            descriptionAr: "",
          }
        : null,
    };
  },
});

/**
 * Get notes for a specific application
 * Gap-fill for WU-14 staff careers data-source routing
 */
export const getApplicationNotes = query({
  args: {
    applicationId: v.string(),
  },
  handler: async (ctx, args) => {
    return await ctx.db
      .query("application_notes")
      .withIndex("by_applicationId", (q) =>
        q.eq("applicationId", args.applicationId),
      )
      .order("desc")
      .collect();
  },
});
