"use client";

/**
 * Komponen pemilih tanggal & jam bersama — satu-satunya tempat aplikasi
 * memakai `react-datepicker`. Semua field tanggal/jam (form & filter) harus
 * lewat sini supaya tampilan + locale konsisten.
 *
 * - `DateField`      → satu tanggal (controlled atau uncontrolled untuk form).
 * - `DateRangeField` → rentang tanggal (berangkat–pulang, filter).
 * - `TimeField`      → jam "HH:mm" (itinerary).
 *
 * Tema visual di-override di `app/globals.css` (blok `.react-datepicker`).
 */

import { useState } from "react";
import ReactDatePicker, { registerLocale } from "react-datepicker";
import { id as idLocale } from "date-fns/locale";
import "react-datepicker/dist/react-datepicker.css";
import {
  formatLocalCalendarYmd,
  localCalendarDateFromYmd,
} from "@/lib/trip-dates";
import { isValidTimeFormat } from "@/lib/itinerary";

registerLocale("id", idLocale);

const FIELD_CLS =
  "w-full rounded-xl border border-neutral-200 bg-neutral-50 py-2.5 pl-9 pr-3 text-sm text-neutral-800 placeholder:text-neutral-400 focus:border-primary-500 focus:bg-white";

function CalendarIcon() {
  return (
    <span className="pointer-events-none absolute left-3 top-1/2 z-10 -translate-y-1/2 text-neutral-400">
      <svg
        xmlns="http://www.w3.org/2000/svg"
        viewBox="0 0 20 20"
        fill="currentColor"
        className="h-4 w-4"
      >
        <path
          fillRule="evenodd"
          d="M5.75 2a.75.75 0 01.75.75V4h7V2.75a.75.75 0 011.5 0V4h.25A2.75 2.75 0 0118 6.75v8.5A2.75 2.75 0 0115.25 18H4.75A2.75 2.75 0 012 15.25v-8.5A2.75 2.75 0 014.75 4H5V2.75A.75.75 0 015.75 2zm-1 5.5c-.69 0-1.25.56-1.25 1.25v6.5c0 .69.56 1.25 1.25 1.25h10.5c.69 0 1.25-.56 1.25-1.25v-6.5c0-.69-.56-1.25-1.25-1.25H4.75z"
          clipRule="evenodd"
        />
      </svg>
    </span>
  );
}

function ClockIcon() {
  return (
    <span className="pointer-events-none absolute left-3 top-1/2 z-10 -translate-y-1/2 text-neutral-400">
      <svg
        xmlns="http://www.w3.org/2000/svg"
        viewBox="0 0 20 20"
        fill="currentColor"
        className="h-4 w-4"
      >
        <path
          fillRule="evenodd"
          d="M10 18a8 8 0 100-16 8 8 0 000 16zm.75-13a.75.75 0 00-1.5 0v5c0 .284.16.544.415.67l3 1.5a.75.75 0 00.67-1.34L10.75 9.54V5z"
          clipRule="evenodd"
        />
      </svg>
    </span>
  );
}

interface DateFieldProps {
  /** Mode controlled. Kalau `undefined`, komponen jalan uncontrolled. */
  value?: Date | null;
  /** Nilai awal untuk mode uncontrolled (mis. di dalam form GET/POST biasa). */
  defaultValue?: Date | null;
  /**
   * Nilai awal uncontrolled berupa `YYYY-MM-DD`. Dipakai saat parent adalah
   * Server Component (mis. filter admin) — string di-parse di browser supaya
   * tidak ada pergeseran timezone server↔klien.
   */
  defaultValueYmd?: string;
  onChange?: (date: Date | null) => void;
  /** Kalau diisi, render hidden input `YYYY-MM-DD` supaya ikut ter-submit form. */
  name?: string;
  id?: string;
  minDate?: Date;
  maxDate?: Date;
  placeholder?: string;
  disabled?: boolean;
  required?: boolean;
  /** Dropdown bulan + tahun — cocok untuk tanggal lahir. */
  withMonthYearDropdown?: boolean;
}

/** Pemilih satu tanggal. */
export function DateField({
  value,
  defaultValue = null,
  defaultValueYmd,
  onChange,
  name,
  id,
  minDate,
  maxDate,
  placeholder = "Pilih tanggal...",
  disabled = false,
  required = false,
  withMonthYearDropdown = false,
}: DateFieldProps) {
  const isControlled = value !== undefined;
  const [internal, setInternal] = useState<Date | null>(
    () => (defaultValueYmd ? localCalendarDateFromYmd(defaultValueYmd) : defaultValue)
  );
  const current = isControlled ? value : internal;

  function handleChange(date: Date | null) {
    if (!isControlled) setInternal(date);
    onChange?.(date);
  }

  // Default rentang masuk akal untuk picker bulan/tahun (mis. tanggal lahir).
  const effectiveMin =
    minDate ??
    (withMonthYearDropdown
      ? new Date(new Date().getFullYear() - 120, 0, 1)
      : undefined);

  return (
    <div className="relative">
      <CalendarIcon />
      <ReactDatePicker
        id={id}
        selected={current ?? null}
        onChange={handleChange}
        locale="id"
        dateFormat="dd MMM yyyy"
        minDate={effectiveMin}
        maxDate={maxDate}
        disabled={disabled}
        required={required}
        placeholderText={placeholder}
        isClearable={!required && !disabled}
        showMonthDropdown={withMonthYearDropdown}
        showYearDropdown={withMonthYearDropdown}
        dropdownMode="select"
        className={FIELD_CLS}
        wrapperClassName="w-full"
      />
      {name && (
        <input
          type="hidden"
          name={name}
          value={current ? formatLocalCalendarYmd(current) : ""}
        />
      )}
    </div>
  );
}

interface DateRangeFieldProps {
  startDate: Date | null;
  endDate: Date | null;
  onChange: (start: Date | null, end: Date | null) => void;
  minDate?: Date;
  placeholder?: string;
  id?: string;
}

/** Pemilih rentang tanggal (berangkat–pulang, filter). */
export function DateRangeField({
  startDate,
  endDate,
  onChange,
  minDate,
  placeholder = "Pilih tanggal...",
  id,
}: DateRangeFieldProps) {
  return (
    <div className="relative">
      <CalendarIcon />
      <ReactDatePicker
        id={id}
        selectsRange
        startDate={startDate}
        endDate={endDate}
        onChange={(dates) => {
          const [start, end] = dates as [Date | null, Date | null];
          onChange(start, end);
        }}
        locale="id"
        dateFormat="dd MMM yyyy"
        minDate={minDate}
        isClearable
        placeholderText={placeholder}
        className={FIELD_CLS}
        wrapperClassName="w-full"
      />
    </div>
  );
}

function timeStringToDate(value: string): Date | null {
  if (!isValidTimeFormat(value)) return null;
  const [h, m] = value.split(":").map(Number);
  const d = new Date();
  d.setHours(h, m, 0, 0);
  return d;
}

function dateToTimeString(d: Date): string {
  const h = String(d.getHours()).padStart(2, "0");
  const m = String(d.getMinutes()).padStart(2, "0");
  return `${h}:${m}`;
}

interface TimeFieldProps {
  /** Jam dalam format "HH:mm", atau "" kalau kosong. */
  value: string;
  onChange: (value: string) => void;
  id?: string;
  placeholder?: string;
  disabled?: boolean;
  /** Tampilkan tombol clear (untuk jam opsional, mis. jam selesai). */
  clearable?: boolean;
}

/** Pemilih jam "HH:mm" 24-jam dengan interval 15 menit. */
export function TimeField({
  value,
  onChange,
  id,
  placeholder = "--:--",
  disabled = false,
  clearable = false,
}: TimeFieldProps) {
  return (
    <div className="relative">
      <ClockIcon />
      <ReactDatePicker
        id={id}
        selected={timeStringToDate(value)}
        onChange={(d: Date | null) => onChange(d ? dateToTimeString(d) : "")}
        showTimeSelect
        showTimeSelectOnly
        timeIntervals={15}
        timeCaption="Jam"
        dateFormat="HH:mm"
        timeFormat="HH:mm"
        locale="id"
        disabled={disabled}
        isClearable={clearable && !disabled}
        placeholderText={placeholder}
        className={FIELD_CLS}
        wrapperClassName="w-full"
      />
    </div>
  );
}
