"use client";

import { useForm, useFieldArray, Controller } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { useState, useTransition, useCallback, useEffect } from "react";
import { useRouter } from "next/navigation";
import {
  User,
  Users,
  Wallet,
  FileText,
  Globe2,
  Plus,
  Calculator,
  ArrowRight,
  AlertCircle,
  Check,
} from "lucide-react";
import { bookingFormSchema, type BookingFormValues } from "@/lib/validators/schemas";
import { createBooking, previewBookingPrice } from "@/services/booking.service";
import { formatCurrency } from "@/lib/formatters/currency";
import ParticipantFields from "./ParticipantFields";
import type { OpenTripDetail } from "@/types/trip";
import type { BookingPricePreview } from "@/types/booking";
import styles from "./BookingForm.module.css";

interface BookingFormProps {
  trip: OpenTripDetail;
}

// Backend membatasi participant_count maksimal 20 per booking (StorePublicBookingRequest)
const HARD_MAX_PARTICIPANTS = 20;

function buildEmptyParticipant(defaultMeetingPointId: string | null) {
  return {
    name: "",
    birth_date: "",
    weight_kg: 0,
    height_cm: 0,
    gender: "MALE" as const,
    whatsapp: "",
    emergency_whatsapp: "",
    medical_history: [] as string[],
    meeting_point_id: defaultMeetingPointId,
  };
}

export default function BookingForm({ trip }: BookingFormProps) {
  const router = useRouter();
  const maxParticipants =
    trip.operational_quota.mode === "LIMITED" && trip.operational_quota.quota !== null
      ? Math.min(trip.operational_quota.quota, HARD_MAX_PARTICIPANTS)
      : HARD_MAX_PARTICIPANTS;

  const [isPending, startTransition] = useTransition();
  const [submitError, setSubmitError] = useState<string | null>(null);
  const [pricePreview, setPricePreview] = useState<BookingPricePreview | null>(null);
  const [isPreviewing, setIsPreviewing] = useState(false);
  const [agreedToTerms, setAgreedToTerms] = useState(true);

  const {
    register,
    control,
    handleSubmit,
    setValue,
    watch,
    formState: { errors },
  } = useForm<BookingFormValues>({
    resolver: zodResolver(bookingFormSchema),
    defaultValues: {
      participant_status: "WNI",
      booker: { name: "", email: "", whatsapp: "" },
      payment_plan: "FULL",
      participants: [buildEmptyParticipant(trip.meeting_points[0]?.id ?? null)],
      notes: "",
    },
  });

  const { fields, append, remove } = useFieldArray({ control, name: "participants" });

  const watchedPaymentPlan = watch("payment_plan");
  const watchedParticipantStatus = watch("participant_status");
  const watchedParticipants = watch("participants");
  const participantCount = fields.length;

  // Meeting point kini dipilih per-peserta — kunci string stabil dari seluruh pilihan
  // dipakai sebagai dependency (array/object dari watch() berubah referensinya tiap
  // render meski isinya sama, string tidak).
  const meetingPointIdsKey = watchedParticipants.map((p) => p.meeting_point_id ?? "").join("|");

  // Live price preview — dihitung otomatis setiap meeting point (per peserta), status
  // peserta, atau jumlah peserta berubah, tidak lagi lewat tombol manual.
  const fetchPreview = useCallback(async () => {
    if (!participantCount) return;
    setIsPreviewing(true);
    try {
      const preview = await previewBookingPrice({
        trip_schedule_id: trip.id,
        meeting_point_ids: watchedParticipants.map((p) => p.meeting_point_id ?? null),
        participant_status: watchedParticipantStatus,
      });
      setPricePreview(preview);
    } catch {
      setPricePreview(null);
    } finally {
      setIsPreviewing(false);
    }
    // meetingPointIdsKey mewakili isi watchedParticipants (lihat komentar di atas) —
    // sengaja tidak memasukkan watchedParticipants langsung sebagai dependency.
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [trip.id, watchedParticipantStatus, participantCount, meetingPointIdsKey]);

  useEffect(() => {
    fetchPreview();
  }, [fetchPreview]);

  const onSubmit = (data: BookingFormValues) => {
    if (!agreedToTerms) {
      setSubmitError("Anda harus menyetujui syarat & ketentuan untuk melanjutkan.");
      return;
    }
    setSubmitError(null);
    startTransition(async () => {
      try {
        const booking = await createBooking({
          trip_schedule_id: trip.id,
          customer: {
            name: data.booker.name,
            email: data.booker.email || undefined,
            whatsapp: data.booker.whatsapp,
          },
          participant_count: data.participants.length,
          participant_status: data.participant_status,
          payment_plan: data.payment_plan,
          participants: data.participants,
          notes: data.notes || undefined,
        });
        router.push(`/payment/${booking.payment_token}`);
      } catch (err) {
        setSubmitError(
          err instanceof Error
            ? err.message
            : "Gagal membuat booking. Silakan coba kembali."
        );
      }
    });
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)} className={styles.formContainer} noValidate>
      {/* ── Section 1: Status Peserta ──────────────────────────────────── */}
      <div className={styles.formCard}>
        <div className={styles.cardHeader}>
          <div className={styles.cardHeaderIconWrap} aria-hidden="true">
            <Globe2 size={20} className={styles.cardHeaderIcon} />
          </div>
          <div className={styles.cardHeaderText}>
            <h2 className={styles.cardTitle}>Status Peserta</h2>
            <p className={styles.cardSubtitle}>
              Meeting point kini dipilih per-peserta — isi di bagian &ldquo;Data Peserta&rdquo; di bawah.
            </p>
          </div>
        </div>

        <div className={styles.formGroup}>
          <label htmlFor="participant-status-select" className={styles.formLabel}>
            Status Warga Negara <span className={styles.requiredStar}>*</span>
          </label>
          <div className={styles.selectWrapper}>
            <select
              id="participant-status-select"
              className={`${styles.formSelect} ${errors.participant_status ? styles.inputError : ""}`}
              {...register("participant_status")}
            >
              <option value="WNI">WNI (Warga Negara Indonesia)</option>
              <option value="WNA">WNA (Warga Negara Asing)</option>
            </select>
          </div>
          {errors.participant_status && (
            <span className={styles.errorText}>{errors.participant_status.message}</span>
          )}
        </div>
      </div>

      {/* ── Section 2: Data Pemesan ──────────────────────────────────── */}
      <div className={styles.formCard}>
        <div className={styles.cardHeader}>
          <div className={styles.cardHeaderIconWrap} aria-hidden="true">
            <User size={20} className={styles.cardHeaderIcon} />
          </div>
          <div className={styles.cardHeaderText}>
            <h2 className={styles.cardTitle}>Data Pemesan</h2>
            <p className={styles.cardSubtitle}>
              Akan dihubungi via WhatsApp untuk konfirmasi booking.
            </p>
          </div>
        </div>

        <div className={styles.gridTwoCols}>
          <div className={styles.formGroup}>
            <label htmlFor="booker-name" className={styles.formLabel}>
              Nama Lengkap <span className={styles.requiredStar}>*</span>
            </label>
            <input
              id="booker-name"
              type="text"
              placeholder="Nama sesuai KTP"
              className={`${styles.formInput} ${errors.booker?.name ? styles.inputError : ""}`}
              {...register("booker.name")}
            />
            {errors.booker?.name && (
              <span className={styles.errorText}>{errors.booker.name.message}</span>
            )}
          </div>

          <div className={styles.formGroup}>
            <label htmlFor="booker-email" className={styles.formLabel}>
              Email
            </label>
            <input
              id="booker-email"
              type="email"
              placeholder="email@contoh.com (opsional)"
              className={`${styles.formInput} ${errors.booker?.email ? styles.inputError : ""}`}
              {...register("booker.email")}
            />
            {errors.booker?.email && (
              <span className={styles.errorText}>{errors.booker.email.message}</span>
            )}
          </div>
        </div>

        <div className={styles.formGroup}>
          <label htmlFor="booker-whatsapp" className={styles.formLabel}>
            Nomor WhatsApp <span className={styles.requiredStar}>*</span>
          </label>
          <div className={styles.phoneInputGroup}>
            <span className={styles.phonePrefix}>+62</span>
            <input
              id="booker-whatsapp"
              type="tel"
              placeholder="8123456789"
              className={`${styles.phoneInput} ${errors.booker?.whatsapp ? styles.inputError : ""}`}
              {...register("booker.whatsapp")}
            />
          </div>
          <span className={styles.fieldHint}>Format: 812xxx atau 62812xxx</span>
          {errors.booker?.whatsapp && (
            <span className={styles.errorText}>{errors.booker.whatsapp.message}</span>
          )}
        </div>
      </div>

      {/* ── Section 3: Data Peserta ──────────────────────────────────── */}
      <div className={styles.formCard}>
        <div className={styles.cardHeader}>
          <div className={styles.cardHeaderIconWrap} aria-hidden="true">
            <Users size={20} className={styles.cardHeaderIcon} />
          </div>
          <div className={styles.cardHeaderText}>
            <h2 className={styles.cardTitle}>Data Peserta</h2>
            <p className={styles.cardSubtitle}>
              Isi data lengkap setiap peserta yang akan mendaki. Maksimal {maxParticipants} peserta per booking.
            </p>
          </div>
        </div>

        {/* Dynamic Participant Cards */}
        <div className={styles.participantsList}>
          {fields.map((field, idx) => (
            <ParticipantFields
              key={field.id}
              index={idx}
              control={control}
              register={register}
              setValue={setValue}
              errors={errors}
              canRemove={fields.length > 1}
              onRemove={() => remove(idx)}
              meetingPoints={trip.meeting_points}
            />
          ))}
        </div>

        {/* Add Participant Button */}
        {fields.length < maxParticipants && (
          <button
            type="button"
            onClick={() => append(buildEmptyParticipant(trip.meeting_points[0]?.id ?? null))}
            className={styles.addParticipantBtn}
            id="add-participant-btn"
          >
            <Plus size={16} aria-hidden="true" />
            <span>Tambah Peserta</span>
          </button>
        )}

        {typeof errors.participants?.message === "string" && (
          <p className={styles.generalError} role="alert">
            {errors.participants.message}
          </p>
        )}
      </div>

      {/* ── Section 4: Metode Pembayaran ──────────────────────────────── */}
      <div className={styles.formCard}>
        <div className={styles.cardHeader}>
          <div className={styles.cardHeaderIconWrap} aria-hidden="true">
            <Wallet size={20} className={styles.cardHeaderIcon} />
          </div>
          <div className={styles.cardHeaderText}>
            <h2 className={styles.cardTitle}>Metode Pembayaran</h2>
            <p className={styles.cardSubtitle}>
              Bayar penuh sekarang, atau DP 50% dan lunasi sisanya nanti.
            </p>
          </div>
        </div>

        <Controller
          name="payment_plan"
          control={control}
          render={({ field }) => (
            <div className={styles.paymentPlansGrid}>
              {/* Option 1: Bayar Penuh */}
              <button
                type="button"
                onClick={() => field.onChange("FULL")}
                className={`${styles.paymentPlanCard} ${field.value === "FULL" ? styles.paymentPlanActive : ""}`}
                id="payment-plan-full"
                aria-pressed={field.value === "FULL"}
              >
                <div className={styles.paymentPlanRadio}>
                  <div className={styles.radioDot} />
                </div>
                <div className={styles.paymentPlanInfo}>
                  <strong className={styles.paymentPlanTitle}>Bayar Penuh</strong>
                  <span className={styles.paymentPlanDesc}>Lunasi sekaligus di awal.</span>
                </div>
                {pricePreview && (
                  <div className={styles.paymentPlanAmount}>
                    {formatCurrency(pricePreview.grand_total)}
                  </div>
                )}
              </button>

              {/* Option 2: DP 50% */}
              <button
                type="button"
                onClick={() => field.onChange("DOWN_PAYMENT")}
                className={`${styles.paymentPlanCard} ${field.value === "DOWN_PAYMENT" ? styles.paymentPlanActive : ""}`}
                id="payment-plan-dp"
                aria-pressed={field.value === "DOWN_PAYMENT"}
              >
                <div className={styles.paymentPlanRadio}>
                  <div className={styles.radioDot} />
                </div>
                <div className={styles.paymentPlanInfo}>
                  <strong className={styles.paymentPlanTitle}>DP 50%</strong>
                  <span className={styles.paymentPlanDesc}>Bayar setengah dulu, lunasi sisanya nanti.</span>
                </div>
                {pricePreview && (
                  <div className={styles.paymentPlanAmount}>
                    {formatCurrency(pricePreview.down_payment_amount)}
                  </div>
                )}
              </button>
            </div>
          )}
        />

        {/* Estimasi biaya dihitung otomatis — lihat useEffect di atas */}
        <div className={styles.estimationWrapper}>
          {isPreviewing ? (
            <p className={styles.emptyNote}>
              <Calculator size={16} aria-hidden="true" /> Menghitung estimasi biaya...
            </p>
          ) : !pricePreview ? (
            <p className={styles.emptyNote}>
              <Calculator size={16} aria-hidden="true" /> Lengkapi data peserta untuk melihat estimasi biaya.
            </p>
          ) : (
            <div className={styles.priceBreakdownBox}>
              <h4 className={styles.breakdownHeading}>Rincian Biaya</h4>
              <div className={styles.breakdownRow}>
                <span>
                  Harga Trip (x{pricePreview.participant_count} Peserta) {pricePreview.participant_status}
                </span>
                <span>{formatCurrency(pricePreview.trip_price * pricePreview.participant_count)}</span>
              </div>
              {pricePreview.meeting_point_breakdown.map((mp) => (
                <div className={styles.breakdownRow} key={mp.name}>
                  <span>
                    Meeting Point {mp.name} (x{mp.count} Peserta)
                  </span>
                  <span>{formatCurrency(mp.price * mp.count)}</span>
                </div>
              ))}
              <div className={`${styles.breakdownRow} ${styles.breakdownTotalRow}`}>
                <strong>Total Pembayaran</strong>
                <strong>{formatCurrency(pricePreview.grand_total)}</strong>
              </div>
              {watchedPaymentPlan === "DOWN_PAYMENT" && (
                <div className={`${styles.breakdownRow} ${styles.breakdownDpRow}`}>
                  <span>Dibayar Sekarang (DP 50%)</span>
                  <span className={styles.dpHighlight}>
                    {formatCurrency(pricePreview.down_payment_amount)}
                  </span>
                </div>
              )}
            </div>
          )}
        </div>
      </div>

      {/* ── Section 5: Catatan ────────────────────────────────────────── */}
      <div className={styles.formCard}>
        <div className={styles.cardHeader}>
          <div className={styles.cardHeaderIconWrap} aria-hidden="true">
            <FileText size={20} className={styles.cardHeaderIcon} />
          </div>
          <div className={styles.cardHeaderText}>
            <h2 className={styles.cardTitle}>Catatan (opsional)</h2>
            <p className={styles.cardSubtitle}>
              Informasi tambahan untuk tim kami (misal: preferensi alat, alergi, dll.)
            </p>
          </div>
        </div>

        <div className={styles.formGroup}>
          <textarea
            id="booking-notes"
            placeholder="Tulis informasi tambahan atau permintaan khusus di sini..."
            rows={3}
            className={`${styles.formTextarea} ${errors.notes ? styles.inputError : ""}`}
            {...register("notes")}
          />
          {errors.notes && (
            <span className={styles.errorText}>{errors.notes.message}</span>
          )}
        </div>
      </div>

      {/* ── Submit Error Banner ──────────────────────────────────────── */}
      {submitError && (
        <div className={styles.errorBanner} role="alert">
          <AlertCircle size={18} aria-hidden="true" />
          <span>{submitError}</span>
        </div>
      )}

      {/* ── Section 6: Agreement & Submit ─────────────────────────────── */}
      <div className={styles.agreementAndSubmitRow}>
        <label className={styles.checkboxLabel}>
          <input
            type="checkbox"
            checked={agreedToTerms}
            onChange={(e) => setAgreedToTerms(e.target.checked)}
            className={styles.realCheckbox}
          />
          <span className={styles.customCheckbox}>
            {agreedToTerms && <Check size={14} strokeWidth={3} />}
          </span>
          <span className={styles.checkboxText}>
            Dengan menekan tombol ini, Anda menyetujui{" "}
            <a
              href="/syarat-ketentuan"
              target="_blank"
              rel="noopener noreferrer"
              className={styles.termsLink}
            >
              syarat & ketentuan
            </a>{" "}
            PPT Adventure.
          </span>
        </label>

        <button
          type="submit"
          disabled={isPending || !agreedToTerms}
          className={styles.submitBookingBtn}
          id="booking-submit-btn"
        >
          <span>{isPending ? "Memproses..." : "Konfirmasi Booking"}</span>
          <ArrowRight size={18} className={styles.submitArrow} />
        </button>
      </div>
    </form>
  );
}
