"use client";

import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { useState, useTransition, useRef } from "react";
import { useRouter } from "next/navigation";
import { Upload, FileImage, AlertCircle, CheckCircle } from "lucide-react";
import { submitPaymentProof } from "@/services/booking.service";
import { formatCurrency } from "@/lib/formatters/currency";
import { paymentProofSchema, type PaymentProofFormValues } from "@/lib/validators/schemas";
import FormField from "@/components/common/FormField";
import SelectField from "@/components/common/SelectField";
import type { PaymentInfo } from "@/types/booking";
import styles from "./PaymentUploadForm.module.css";

interface PaymentUploadFormProps {
  token: string;
  payment: PaymentInfo;
}

export default function PaymentUploadForm({ token, payment }: PaymentUploadFormProps) {
  const router = useRouter();
  const [isPending, startTransition] = useTransition();
  const [file, setFile] = useState<File | null>(null);
  const [preview, setPreview] = useState<string | null>(null);
  const [fileError, setFileError] = useState<string | null>(null);
  const [submitError, setSubmitError] = useState<string | null>(null);
  const [success, setSuccess] = useState(false);
  const fileInputRef = useRef<HTMLInputElement>(null);

  const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm<PaymentProofFormValues>({
    resolver: zodResolver(paymentProofSchema),
    defaultValues: {
      bank_account_id: payment.bank_accounts[0]?.id ?? "",
      transfer_date: new Date().toISOString().slice(0, 10),
      transfer_amount: payment.amount,
      sender_bank: "",
      sender_account_name: "",
      notes: "",
    },
  });

  const handleFile = (f: File) => {
    if (f.size > 5 * 1024 * 1024) {
      setFileError("File terlalu besar. Maksimal 5 MB.");
      return;
    }
    if (!["image/jpeg", "image/jpg", "image/png", "application/pdf"].includes(f.type)) {
      setFileError("Format tidak didukung. Gunakan JPG, PNG, atau PDF.");
      return;
    }
    setFileError(null);
    setFile(f);
    setPreview(f.type === "application/pdf" ? null : URL.createObjectURL(f));
  };

  const handleDrop = (e: React.DragEvent) => {
    e.preventDefault();
    const f = e.dataTransfer.files[0];
    if (f) handleFile(f);
  };

  const onSubmit = (data: PaymentProofFormValues) => {
    if (!file) {
      setFileError("Pilih file bukti pembayaran terlebih dahulu.");
      return;
    }
    setFileError(null);
    setSubmitError(null);

    startTransition(async () => {
      try {
        await submitPaymentProof(token, { ...data, payment_proof: file });
        setSuccess(true);
        setTimeout(() => router.refresh(), 1500);
      } catch (err) {
        setSubmitError(err instanceof Error ? err.message : "Gagal upload. Coba kembali.");
      }
    });
  };

  if (success) {
    return (
      <div className={styles.successState}>
        <CheckCircle size={32} className={styles.successIcon} aria-hidden />
        <p className={styles.successText}>Bukti pembayaran berhasil diupload! Menunggu konfirmasi admin.</p>
      </div>
    );
  }

  if (payment.bank_accounts.length === 0) {
    return (
      <div className={styles.errorMsg} role="alert">
        <AlertCircle size={14} aria-hidden />
        Rekening tujuan belum tersedia. Silakan hubungi admin.
      </div>
    );
  }

  return (
    <form onSubmit={handleSubmit(onSubmit)} className={styles.form} noValidate>
      <SelectField
        label="Transfer ke Rekening"
        required
        error={errors.bank_account_id?.message}
        id="payment-bank-account"
        {...register("bank_account_id")}
      >
        {payment.bank_accounts.map((bank) => (
          <option key={bank.id} value={bank.id}>
            {bank.bank} — {bank.account_number} a.n. {bank.account_holder}
          </option>
        ))}
      </SelectField>

      <div className={styles.grid2}>
        <FormField
          label="Tanggal Transfer"
          required
          type="date"
          error={errors.transfer_date?.message}
          id="payment-transfer-date"
          {...register("transfer_date")}
        />
        <FormField
          label="Jumlah Transfer"
          required
          type="number"
          hint={`Tagihan: ${formatCurrency(payment.amount)}`}
          error={errors.transfer_amount?.message}
          id="payment-transfer-amount"
          {...register("transfer_amount", { valueAsNumber: true })}
        />
        <FormField
          label="Bank Pengirim"
          placeholder="cth. BCA (opsional)"
          error={errors.sender_bank?.message}
          id="payment-sender-bank"
          {...register("sender_bank")}
        />
        <FormField
          label="Nama Pengirim"
          placeholder="Sesuai rekening pengirim (opsional)"
          error={errors.sender_account_name?.message}
          id="payment-sender-name"
          {...register("sender_account_name")}
        />
      </div>

      {/* Drop zone */}
      <div
        className={`${styles.dropZone} ${file ? styles.hasFile : ""}`}
        onDragOver={(e) => e.preventDefault()}
        onDrop={handleDrop}
        role="button"
        tabIndex={0}
        aria-label="Upload bukti pembayaran"
        onClick={() => fileInputRef.current?.click()}
        onKeyDown={(e) => e.key === "Enter" && fileInputRef.current?.click()}
      >
        <input
          ref={fileInputRef}
          type="file"
          accept="image/jpeg,image/png,application/pdf"
          className={styles.fileInput}
          onChange={(e) => { const f = e.target.files?.[0]; if (f) handleFile(f); }}
          id="payment-proof-input"
          aria-label="Pilih file bukti pembayaran"
        />
        {file ? (
          preview ? (
            // eslint-disable-next-line @next/next/no-img-element
            <img src={preview} alt="Preview bukti pembayaran" className={styles.preview} />
          ) : (
            <div className={styles.dropContent}>
              <FileImage size={28} aria-hidden />
              <p className={styles.dropText}>{file.name}</p>
            </div>
          )
        ) : (
          <div className={styles.dropContent}>
            <div className={styles.dropIcon}>
              <FileImage size={28} aria-hidden />
            </div>
            <p className={styles.dropText}>
              <strong>Klik untuk pilih</strong> atau drag & drop
            </p>
            <p className={styles.dropHint}>JPG, PNG, atau PDF — maks 5 MB</p>
          </div>
        )}
      </div>

      {file && (
        <button
          type="button"
          className="btn btn-ghost btn-sm"
          onClick={() => { setFile(null); setPreview(null); }}
          id="payment-clear-file"
        >
          Ganti File
        </button>
      )}

      {(fileError || submitError) && (
        <div className={styles.errorMsg} role="alert">
          <AlertCircle size={14} aria-hidden />
          {fileError || submitError}
        </div>
      )}

      <button
        type="submit"
        disabled={isPending}
        className="btn btn-primary btn-lg"
        id="payment-upload-submit"
        style={{ justifyContent: "center" }}
      >
        <Upload size={16} aria-hidden />
        {isPending ? "Mengupload..." : "Upload Bukti Bayar"}
      </button>
    </form>
  );
}
