"use client";

import React, { useState, useCallback, ChangeEvent, DragEvent } from "react";
import { FaUpload, FaFileAlt, FaTimes } from "react-icons/fa";
import { useForm, SubmitHandler } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
import Button from "./ui/Button";

const MAX_FILE_SIZE = 5 * 1024 * 1024; // 5MB
const ACCEPTED_FILE_TYPES = [
  "application/pdf",
  "application/msword",
  "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
  "text/plain",
];

const applicationSchema = z.object({
  name: z.string().min(2, "Full name must be at least 2 characters"),
  email: z.string().email("Invalid email address"),
  phone: z.string().optional(),
  linkedin: z.string().url("Invalid URL").optional().or(z.literal("")),
  coverLetter: z.string().optional(),
  resume: z
    .custom<File | null>((val) => val instanceof File, "Resume/CV is required")
    .refine(
      (file) => file && file.size <= MAX_FILE_SIZE,
      `Max file size is 5MB.`
    )
    .refine(
      (file) => file && ACCEPTED_FILE_TYPES.includes(file.type),
      "Unsupported file format. Please upload PDF, DOC, DOCX, or TXT."
    ),
});

type ApplicationFormData = z.infer<typeof applicationSchema>;

interface VacancyApplicationFormProps {
  vacancyId: string;
  vacancyTitle: string;
  onClose: () => void;
}

export default function VacancyApplicationForm({
  vacancyId,
  vacancyTitle,
  onClose,
}: VacancyApplicationFormProps) {
  const {
    register,
    handleSubmit,
    setValue,
    watch,
    formState: { errors, isSubmitting },
    reset,
  } = useForm<ApplicationFormData>({
    resolver: zodResolver(applicationSchema),
    mode: "onChange",
    defaultValues: {
      name: "",
      email: "",
      phone: "",
      linkedin: "",
      coverLetter: "",
      resume: null,
    },
  });

  const resumeFile = watch("resume");
  const [isDragging, setIsDragging] = useState(false);
  const [submitStatus, setSubmitStatus] = useState<
    "idle" | "success" | "error"
  >("idle");

  const handleFileChange = (e: ChangeEvent<HTMLInputElement>) => {
    if (e.target.files && e.target.files.length > 0) {
      setValue("resume", e.target.files[0], { shouldValidate: true });
      e.target.value = "";
    }
  };

  const handleDragEnter = useCallback((e: DragEvent<HTMLDivElement>) => {
    e.preventDefault();
    e.stopPropagation();
    setIsDragging(true);
  }, []);

  const handleDragLeave = useCallback((e: DragEvent<HTMLDivElement>) => {
    e.preventDefault();
    e.stopPropagation();
    setIsDragging(false);
  }, []);

  const handleDragOver = useCallback(
    (e: DragEvent<HTMLDivElement>) => {
      e.preventDefault();
      e.stopPropagation();
      if (!isDragging) setIsDragging(true);
    },
    [isDragging]
  );

  const handleDrop = useCallback(
    (e: DragEvent<HTMLDivElement>) => {
      e.preventDefault();
      e.stopPropagation();
      setIsDragging(false);
      if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {
        setValue("resume", e.dataTransfer.files[0], { shouldValidate: true });
        e.dataTransfer.clearData();
      }
    },
    [setValue]
  );

  const removeFile = () => {
    setValue("resume", null, { shouldValidate: true });
  };

  const onSubmit: SubmitHandler<ApplicationFormData> = async (data) => {
    setSubmitStatus("idle");
    const formData = new FormData();
    formData.append("vacancyId", vacancyId);
    formData.append("vacancyTitle", vacancyTitle);
    formData.append("name", data.name);
    formData.append("email", data.email);
    if (data.phone) formData.append("phone", data.phone);
    if (data.linkedin) formData.append("linkedin", data.linkedin);
    if (data.coverLetter) formData.append("coverLetter", data.coverLetter);
    if (data.resume) formData.append("resume", data.resume, data.resume.name);

    try {
      const response = await fetch("/api/apply", {
        method: "POST",
        body: formData,
      });
      if (!response.ok)
        throw new Error(`Submission failed: ${response.statusText}`);
      setSubmitStatus("success");
      reset();
      setTimeout(() => {
        onClose();
        setSubmitStatus("idle");
      }, 1500);
    } catch (error) {
      console.error(error);
      setSubmitStatus("error");
    }
  };

  const inputBaseStyle =
    "block w-full px-4 py-2 mt-1 text-gray-700 bg-white border border-gray-300 rounded-md focus:border-gold-500 focus:ring focus:ring-gold-500 focus:ring-opacity-50 dark:bg-gray-800 dark:text-gray-300 dark:border-gray-600 dark:focus:border-gold-500 font-poppins";
  const errorStyle = "border-red-500 focus:border-red-500 focus:ring-red-500";
  const errorMessageStyle = "text-red-600 text-xs mt-1";

  return (
    <form onSubmit={handleSubmit(onSubmit)} className="space-y-6 font-poppins">
      {/* Row 1: Name & Email */}
      <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
        {/* Name Field */}
        <div>
          <label htmlFor="name" className="text-gray-700 dark:text-gray-200">
            Full Name *
          </label>
          <input
            id="name"
            type="text"
            {...register("name")}
            className={`${inputBaseStyle} ${errors.name ? errorStyle : ""}`}
            aria-invalid={errors.name ? "true" : "false"}
          />
          {errors.name && (
            <p role="alert" className={errorMessageStyle}>
              {errors.name.message}
            </p>
          )}
        </div>

        {/* Email Field */}
        <div>
          <label htmlFor="email" className="text-gray-700 dark:text-gray-200">
            Email Address *
          </label>
          <input
            id="email"
            type="email"
            {...register("email")}
            className={`${inputBaseStyle} ${errors.email ? errorStyle : ""}`}
            aria-invalid={errors.email ? "true" : "false"}
          />
          {errors.email && (
            <p role="alert" className={errorMessageStyle}>
              {errors.email.message}
            </p>
          )}
        </div>
      </div>

      {/* Row 2: Phone & LinkedIn */}
      <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
        {/* Phone Field */}
        <div>
          <label htmlFor="phone" className="text-gray-700 dark:text-gray-200">
            Phone Number
          </label>
          <input
            id="phone"
            type="tel"
            {...register("phone")}
            className={`${inputBaseStyle} ${errors.phone ? errorStyle : ""}`}
            aria-invalid={errors.phone ? "true" : "false"}
          />
          {errors.phone && (
            <p role="alert" className={errorMessageStyle}>
              {errors.phone.message}
            </p>
          )}
        </div>

        {/* LinkedIn Field */}
        <div>
          <label
            htmlFor="linkedin"
            className="text-gray-700 dark:text-gray-200"
          >
            LinkedIn Profile URL
          </label>
          <input
            id="linkedin"
            type="url"
            {...register("linkedin")}
            className={`${inputBaseStyle} ${errors.linkedin ? errorStyle : ""}`}
            placeholder="https://linkedin.com/in/yourprofile"
            aria-invalid={errors.linkedin ? "true" : "false"}
          />
          {errors.linkedin && (
            <p role="alert" className={errorMessageStyle}>
              {errors.linkedin.message}
            </p>
          )}
        </div>
      </div>

      {/* Resume/CV Upload */}
      <div>
        <label className="text-gray-700 dark:text-gray-200 block mb-2">
          Resume/CV *
        </label>
        <input
          id="resume-upload-hidden"
          type="file"
          onChange={handleFileChange}
          accept=".pdf,.doc,.docx,.txt"
          className="hidden"
          aria-hidden="true"
        />
        <div
          className={`relative flex flex-col items-center justify-center w-full p-6 transition-colors duration-300 ease-in-out border-2 border-dashed rounded-lg cursor-pointer hover:border-gold-500/80 ${
            isDragging
              ? "border-gold-500 bg-gold-50"
              : errors.resume
              ? "border-red-500"
              : "border-gray-300 hover:bg-gray-50"
          }`}
          onDragEnter={handleDragEnter}
          onDragLeave={handleDragLeave}
          onDragOver={handleDragOver}
          onDrop={handleDrop}
          onClick={() =>
            document.getElementById("resume-upload-hidden")?.click()
          }
          role="button"
          tabIndex={0}
          onKeyDown={(e) => {
            if (e.key === "Enter" || e.key === " ")
              document.getElementById("resume-upload-hidden")?.click();
          }}
          aria-label="Upload Resume/CV"
        >
          <FaUpload
            className={`w-8 h-8 mb-3 ${
              isDragging ? "text-gold-600" : "text-gray-400"
            }`}
            style={{ color: isDragging ? "#c8a93d" : undefined }}
          />
          <p
            className={`text-sm font-semibold text-center ${
              isDragging ? "text-gold-700" : "text-gray-600"
            }`}
          >
            {isDragging ? "Drop file here" : "Drag & drop your file here"}
          </p>
          <p className="text-xs text-gray-500 text-center">
            or click to browse
          </p>
          <p className="mt-2 text-xs text-gray-500">
            (PDF, DOC, DOCX, TXT - Max 5MB)
          </p>
        </div>
        {errors.resume && (
          <p role="alert" className={errorMessageStyle}>
            {(errors.resume as unknown as { message: string }).message}
          </p>
        )}
        {resumeFile && (
          <div className="mt-3 flex items-center justify-between px-3 py-2 text-sm text-gray-700 bg-gray-100 border border-gray-200 rounded-md">
            <div className="flex items-center gap-2">
              <FaFileAlt className="w-4 h-4 text-gray-500" />
              <span className="font-medium truncate max-w-[200px] sm:max-w-xs">
                {resumeFile.name}
              </span>
              <span className="text-xs text-gray-500">
                ({(resumeFile.size / 1024).toFixed(1)} KB)
              </span>
            </div>
            <button
              type="button"
              onClick={removeFile}
              className="text-red-500 hover:text-red-700 focus:outline-none"
              aria-label="Remove file"
            >
              <FaTimes className="w-4 h-4" />
            </button>
          </div>
        )}
      </div>

      {/* Cover Letter Field */}
      <div>
        <label
          htmlFor="coverLetter"
          className="text-gray-700 dark:text-gray-200"
        >
          Cover Letter (Optional)
        </label>
        <textarea
          id="coverLetter"
          rows={4}
          {...register("coverLetter")} // Register with RHF
          className={`${inputBaseStyle} resize-vertical ${
            errors.coverLetter ? errorStyle : ""
          }`}
          aria-invalid={errors.coverLetter ? "true" : "false"}
        ></textarea>
        {errors.coverLetter && (
          <p role="alert" className={errorMessageStyle}>
            {errors.coverLetter.message}
          </p>
        )}
      </div>

      {/* Submit Button & Status */}
      <div className="flex flex-col items-center space-y-3 pt-4">
        <Button
          type="submit"
          disabled={isSubmitting || submitStatus === "success"} // Disable while submitting or on success
        >
          {isSubmitting ? "Submitting..." : "Submit Application"}
        </Button>

        {submitStatus === "success" && (
          <p className="text-sm text-green-600">
            Application submitted successfully! Closing form...
          </p>
        )}
        {submitStatus === "error" && (
          <p className="text-sm text-red-600">
            Submission failed. Please check your details and try again.
          </p>
        )}
      </div>
    </form>
  );
}
