/**
 * Mawidi Demo Scheduler - Booking Form Component
 * Collects user information for booking confirmation
 */

"use client";

import React, { useState } from "react";
import type { UserInfo, FormErrors } from "../types/scheduler.types";
import {
  validateEmail,
  validatePhoneNumber,
  validateName,
  validateMessage,
  sanitizeInput,
} from "../utils/validationHelpers";

export interface BookingFormProps {
  /** User information state */
  userInfo: Partial<UserInfo>;
  /** Callback when form data changes */
  onChange: (userInfo: Partial<UserInfo>) => void;
  /** Form errors */
  errors?: FormErrors;
  /** Callback when errors change */
  onErrorsChange?: (errors: FormErrors) => void;
  /** Language for labels */
  language?: "en" | "ar";
  /** Custom className for styling */
  className?: string;
  /** Language direction */
  dir?: "ltr" | "rtl";
}

const formLabels = {
  en: {
    title: "Your information",
    description: "Please provide your contact details",
    name: "Full Name",
    namePlaceholder: "John Doe",
    nameRequired: "Name is required",
    email: "Email Address",
    emailPlaceholder: "john@example.com",
    emailRequired: "Email is required",
    emailInvalid: "Please enter a valid email",
    phone: "Phone Number",
    phonePlaceholder: "501234567",
    phoneRequired: "Phone number is required",
    phoneInvalid: "Phone number must be at least 6 digits",
    countryCode: "Country",
    message: "Message or Special Requirements",
    messagePlaceholder: "Tell us about your needs or any questions you have...",
    messageRequired: "Message is required",
    messageHint: "Minimum 10 characters",
  },
  ar: {
    title: "معلوماتك",
    description: "يرجى تقديم تفاصيل الاتصال الخاصة بك",
    name: "الاسم الكامل",
    namePlaceholder: "محمد أحمد",
    nameRequired: "الاسم مطلوب",
    email: "البريد الإلكتروني",
    emailPlaceholder: "mohammed@example.com",
    emailRequired: "البريد الإلكتروني مطلوب",
    emailInvalid: "يرجى إدخال بريد إلكتروني صالح",
    phone: "رقم الهاتف",
    phonePlaceholder: "٥٠١٢٣٤٥٦٧",
    phoneRequired: "رقم الهاتف مطلوب",
    phoneInvalid: "رقم الهاتف يجب أن يكون 6 أرقام على الأقل",
    countryCode: "الدولة",
    message: "رسالة أو متطلبات خاصة",
    messagePlaceholder: "أخبرنا عن احتياجاتك أو أي أسئلة لديك...",
    messageRequired: "الرسالة مطلوبة",
    messageHint: "الحد الأدنى ١٠ أحرف",
  },
};

// GCC Country codes for dropdown
const countryCodes = [
  { code: "+974", country: "Qatar", countryAr: "قطر", flag: "🇶🇦" },
  { code: "+966", country: "Saudi Arabia", countryAr: "السعودية", flag: "🇸🇦" },
  { code: "+971", country: "UAE", countryAr: "الإمارات", flag: "🇦🇪" },
  { code: "+965", country: "Kuwait", countryAr: "الكويت", flag: "🇰🇼" },
  { code: "+973", country: "Bahrain", countryAr: "البحرين", flag: "🇧🇭" },
  { code: "+968", country: "Oman", countryAr: "عمان", flag: "🇴🇲" },
  { code: "other", country: "Other", countryAr: "أخرى", flag: "🌍" },
];

/**
 * BookingForm Component
 *
 * Collects and validates user contact information
 * Supports real-time validation and sanitization
 *
 * @example
 * ```tsx
 * <BookingForm
 *   userInfo={userInfo}
 *   onChange={(info) => setUserInfo(info)}
 *   errors={errors}
 *   language="en"
 * />
 * ```
 */
export default function BookingForm({
  userInfo,
  onChange,
  errors = {},
  onErrorsChange,
  language = "en",
  className = "",
  dir = "ltr",
}: BookingFormProps) {
  const labels = formLabels[language];
  const [touched, setTouched] = useState<Set<string>>(new Set());
  const [countryCode, setCountryCode] = useState<string>("+974"); // Default to Qatar
  const [phoneNumber, setPhoneNumber] = useState<string>("");
  const [customCountryCode, setCustomCountryCode] = useState<string>("");

  // Initialize phone state from userInfo on mount
  React.useEffect(() => {
    if (userInfo.phone) {
      // Parse existing phone to extract country code and number
      const phone = userInfo.phone;
      const matchedCode = countryCodes.find(
        (c) => c.code !== "other" && phone.startsWith(c.code),
      );

      if (matchedCode) {
        setCountryCode(matchedCode.code);
        setPhoneNumber(phone.substring(matchedCode.code.length));
      } else {
        // Custom country code
        const match = phone.match(/^(\+\d{1,4})(.*)/);
        if (match) {
          setCountryCode("other");
          setCustomCountryCode(match[1]);
          setPhoneNumber(match[2]);
        } else {
          setPhoneNumber(phone);
        }
      }
    }
  }, []); // Only run once on mount

  // Validate field on blur
  const validateField = (field: keyof UserInfo, value: string) => {
    const newErrors = { ...errors };

    switch (field) {
      case "name":
        const nameResult = validateName(value);
        if (!nameResult.valid) {
          newErrors.name = nameResult.error;
        } else {
          delete newErrors.name;
        }
        break;

      case "email":
        const emailResult = validateEmail(value);
        if (!emailResult.valid) {
          newErrors.email = emailResult.error;
        } else {
          delete newErrors.email;
        }
        break;

      case "phone":
        if (!value) {
          // Phone is required
          newErrors.phone =
            language === "ar" ? "رقم الهاتف مطلوب" : "Phone number is required";
        } else {
          // Validate format if provided
          // Remove non-digits for length check
          const digitsOnly = value.replace(/\D/g, "");
          if (digitsOnly.length < 6) {
            newErrors.phone =
              language === "ar"
                ? "رقم الهاتف يجب أن يكون 6 أرقام على الأقل"
                : "Phone number must be at least 6 digits";
          } else {
            delete newErrors.phone;
          }
        }
        break;

      case "message":
        const messageResult = validateMessage(value);
        if (!messageResult.valid) {
          newErrors.message = messageResult.error;
        } else {
          delete newErrors.message;
        }
        break;
    }

    onErrorsChange?.(newErrors);
  };

  const handleChange = (field: keyof UserInfo, value: string) => {
    // Sanitize input
    const sanitized = sanitizeInput(value);

    onChange({
      ...userInfo,
      [field]: sanitized,
    });

    // Validate if field has been touched
    if (touched.has(field)) {
      validateField(field, sanitized);
    }
  };

  const handleBlur = (field: keyof UserInfo) => {
    setTouched((prev) => new Set(prev).add(field));
    const value = userInfo[field] || "";
    validateField(field, value);
  };

  return (
    <div className={`space-y-6 ${className}`} dir={dir}>
      {/* Editorial Title and description */}
      <div className="space-y-2">
        <h3 className="text-xl font-semibold text-[#1E293B] dark:text-white">
          {labels.title}
        </h3>
        <p className="text-sm text-[#64748B] dark:text-slate-400">
          {labels.description}
        </p>
      </div>

      {/* Form fields - Editorial style */}
      <div className="space-y-5">
        {/* Name field */}
        <div>
          <label
            htmlFor="booking-name"
            className="block text-sm font-medium text-[#1E293B] dark:text-white mb-2"
          >
            {labels.name}
            <span className="text-[#10B981] ml-1">*</span>
          </label>
          <input
            id="booking-name"
            type="text"
            value={userInfo.name || ""}
            onChange={(e) => handleChange("name", e.target.value)}
            onBlur={() => handleBlur("name")}
            placeholder={labels.namePlaceholder}
            className={`
              w-full
              px-4
              py-3
              border
              transition-colors duration-200
              bg-white
              dark:bg-slate-900
              text-[#1E293B]
              dark:text-white
              placeholder:text-slate-400
              dark:placeholder:text-slate-500
              ${
                errors.name
                  ? "border-red-500 focus:border-red-500 focus:ring-2 focus:ring-red-500/20"
                  : "border-slate-200 dark:border-slate-700 focus:border-[#10B981] focus:ring-2 focus:ring-[#10B981]/20"
              }
              focus:outline-none
            `}
            aria-invalid={!!errors.name}
            aria-describedby={errors.name ? "name-error" : undefined}
          />
          {errors.name && (
            <p
              id="name-error"
              className="mt-2 text-sm text-red-500 flex items-center gap-2"
            >
              <div className="w-1.5 h-1.5 bg-red-500 flex-shrink-0" />
              {errors.name}
            </p>
          )}
        </div>

        {/* Email field */}
        <div>
          <label
            htmlFor="booking-email"
            className="block text-sm font-medium text-[#1E293B] dark:text-white mb-2"
          >
            {labels.email}
            <span className="text-[#10B981] ml-1">*</span>
          </label>
          <input
            id="booking-email"
            type="email"
            value={userInfo.email || ""}
            onChange={(e) => handleChange("email", e.target.value)}
            onBlur={() => handleBlur("email")}
            placeholder={labels.emailPlaceholder}
            className={`
              w-full
              px-4
              py-3
              border
              transition-colors duration-200
              bg-white
              dark:bg-slate-900
              text-[#1E293B]
              dark:text-white
              placeholder:text-slate-400
              dark:placeholder:text-slate-500
              ${
                errors.email
                  ? "border-red-500 focus:border-red-500 focus:ring-2 focus:ring-red-500/20"
                  : "border-slate-200 dark:border-slate-700 focus:border-[#10B981] focus:ring-2 focus:ring-[#10B981]/20"
              }
              focus:outline-none
            `}
            aria-invalid={!!errors.email}
            aria-describedby={errors.email ? "email-error" : undefined}
          />
          {errors.email && (
            <p
              id="email-error"
              className="mt-2 text-sm text-red-500 flex items-center gap-2"
            >
              <div className="w-1.5 h-1.5 bg-red-500 flex-shrink-0" />
              {errors.email}
            </p>
          )}
        </div>

        {/* Phone field with country code dropdown (required) */}
        <div>
          <label
            htmlFor="booking-phone"
            className="block text-sm font-medium text-[#1E293B] dark:text-white mb-2"
          >
            {labels.phone}
            <span className="text-[#10B981] ml-1">*</span>
          </label>
          <div className="flex gap-px bg-slate-200 dark:bg-slate-700">
            {/* Country Code Dropdown */}
            <div className="relative w-32 sm:w-36">
              <select
                id="country-code"
                value={countryCode}
                onChange={(e) => {
                  const newCode = e.target.value;
                  setCountryCode(newCode);

                  // Update full phone number in userInfo
                  if (phoneNumber) {
                    const fullPhone =
                      newCode === "other"
                        ? `${customCountryCode || "+"}${phoneNumber}`
                        : `${newCode}${phoneNumber}`;
                    handleChange("phone", fullPhone);
                  }
                }}
                className={`
                  w-full
                  px-3
                  py-3
                  border-0
                  transition-colors duration-200
                  bg-white
                  dark:bg-slate-900
                  text-[#1E293B]
                  dark:text-white
                  focus:outline-none
                  focus:ring-2 focus:ring-[#10B981]/20 focus:ring-inset
                  appearance-none
                  cursor-pointer
                `}
              >
                {countryCodes.map((item) => (
                  <option key={item.code} value={item.code}>
                    {item.flag}{" "}
                    {item.code === "other"
                      ? language === "ar"
                        ? item.countryAr
                        : item.country
                      : item.code}
                  </option>
                ))}
              </select>
              {/* Dropdown arrow */}
              <div className="absolute inset-y-0 right-2 flex items-center pointer-events-none">
                <svg
                  className="w-4 h-4 text-[#64748B]"
                  fill="none"
                  viewBox="0 0 24 24"
                  stroke="currentColor"
                >
                  <path
                    strokeLinecap="round"
                    strokeLinejoin="round"
                    strokeWidth={2}
                    d="M19 9l-7 7-7-7"
                  />
                </svg>
              </div>
            </div>

            {/* Custom Country Code Input (shown when "Other" is selected) */}
            {countryCode === "other" && (
              <input
                type="text"
                placeholder="+123"
                value={customCountryCode}
                onChange={(e) => {
                  const value = e.target.value;
                  // Only allow + and digits
                  if (/^[+\d]*$/.test(value)) {
                    setCustomCountryCode(value);
                    // Update full phone
                    if (phoneNumber) {
                      handleChange("phone", `${value}${phoneNumber}`);
                    }
                  }
                }}
                className="
                  w-20
                  px-3
                  py-3
                  border-0
                  transition-colors duration-200
                  bg-white
                  dark:bg-slate-900
                  text-[#1E293B]
                  dark:text-white
                  placeholder:text-slate-400
                  focus:outline-none
                  focus:ring-2 focus:ring-[#10B981]/20 focus:ring-inset
                "
              />
            )}

            {/* Phone Number Input */}
            <input
              id="booking-phone"
              type="tel"
              value={phoneNumber}
              onChange={(e) => {
                const value = e.target.value;
                // Only allow digits, spaces, dashes
                if (/^[\d\s\-]*$/.test(value)) {
                  setPhoneNumber(value);
                  // Concatenate country code + phone number
                  const fullPhone =
                    countryCode === "other"
                      ? `${customCountryCode || "+"}${value}`
                      : `${countryCode}${value}`;
                  handleChange("phone", fullPhone);
                }
              }}
              onBlur={() => {
                // Validate on blur
                handleBlur("phone");
              }}
              placeholder={labels.phonePlaceholder}
              className="
                flex-1
                px-4
                py-3
                border-0
                transition-colors duration-200
                bg-white
                dark:bg-slate-900
                text-[#1E293B]
                dark:text-white
                placeholder:text-slate-400
                focus:outline-none
                focus:ring-2 focus:ring-[#10B981]/20 focus:ring-inset
              "
              aria-invalid={!!errors.phone}
              aria-describedby={errors.phone ? "phone-error" : undefined}
            />
          </div>
          {errors.phone && (
            <p
              id="phone-error"
              className="mt-2 text-sm text-red-500 flex items-center gap-2"
            >
              <div className="w-1.5 h-1.5 bg-red-500 flex-shrink-0" />
              {errors.phone}
            </p>
          )}
        </div>

        {/* Message field */}
        <div>
          <label
            htmlFor="booking-message"
            className="block text-sm font-medium text-[#1E293B] dark:text-white mb-2"
          >
            {labels.message}
            <span className="text-[#10B981] ml-1">*</span>
          </label>
          <textarea
            id="booking-message"
            value={userInfo.message || ""}
            onChange={(e) => handleChange("message", e.target.value)}
            onBlur={() => handleBlur("message")}
            placeholder={labels.messagePlaceholder}
            rows={4}
            className={`
              w-full
              px-4
              py-3
              border
              transition-colors duration-200
              bg-white
              dark:bg-slate-900
              text-[#1E293B]
              dark:text-white
              placeholder:text-slate-400
              dark:placeholder:text-slate-500
              resize-none
              ${
                errors.message
                  ? "border-red-500 focus:border-red-500 focus:ring-2 focus:ring-red-500/20"
                  : "border-slate-200 dark:border-slate-700 focus:border-[#10B981] focus:ring-2 focus:ring-[#10B981]/20"
              }
              focus:outline-none
            `}
            aria-invalid={!!errors.message}
            aria-describedby={errors.message ? "message-error" : "message-hint"}
          />
          {errors.message ? (
            <p
              id="message-error"
              className="mt-2 text-sm text-red-500 flex items-center gap-2"
            >
              <div className="w-1.5 h-1.5 bg-red-500 flex-shrink-0" />
              {errors.message}
            </p>
          ) : (
            <p
              id="message-hint"
              className="mt-2 text-xs text-[#64748B] dark:text-slate-500 flex items-center gap-2"
            >
              <div className="w-1 h-1 bg-[#64748B] dark:bg-slate-500" />
              {labels.messageHint}
            </p>
          )}
        </div>
      </div>

      {/* Privacy notice - Editorial style */}
      <div className="flex items-start gap-3 p-4 bg-[#FAFAFA] dark:bg-slate-800 border border-slate-200 dark:border-slate-700">
        <div className="w-1.5 h-1.5 bg-[#10B981] mt-2 flex-shrink-0" />
        <p className="text-xs text-[#64748B] dark:text-slate-400">
          {language === "ar"
            ? "معلوماتك آمنة ومشفرة. نستخدم بياناتك فقط لتأكيد حجزك والتواصل معك."
            : "Your information is secure and encrypted. We use your data only to confirm your booking and communicate with you."}
        </p>
      </div>
    </div>
  );
}
