"use client"

import { useEffect, useLayoutEffect, useMemo, useRef, useState } from "react"
import { Check, ChevronDown, Loader2, Search, X } from "lucide-react"

export type DoctorNameLocale = "en" | "ar" | "tr"

export interface HospitalDoctorsSectionData {
  eyebrow: string
  title: string
  primaryButtonText: string
  primaryButtonLink: string
  doctorIds: string[]
}

interface Props {
  value: HospitalDoctorsSectionData
  onChange: (value: HospitalDoctorsSectionData) => void
  doctorNameLocale?: DoctorNameLocale
}

const inputClass =
  "w-full bg-card border border-border rounded-xl px-4 py-2.5 text-sm text-foreground font-sans placeholder:text-muted-foreground outline-none focus:ring-2 focus:ring-[#2BB673]/30 focus:border-[#2BB673] transition-colors"

interface DoctorOption {
  id: string
  name: string
  image?: string
}

export function HospitalDoctorsSection({ value, onChange, doctorNameLocale = "en" }: Props) {
  const triggerRef = useRef<HTMLDivElement | null>(null)
  const [open, setOpen] = useState(false)
  const [query, setQuery] = useState("")
  const [doctors, setDoctors] = useState<DoctorOption[]>([])
  const [loadingDoctors, setLoadingDoctors] = useState(false)
  const [doctorsLoadError, setDoctorsLoadError] = useState<string | null>(null)
  const [dropdownStyle, setDropdownStyle] = useState<React.CSSProperties>({
    position: "fixed",
    top: 0,
    left: 0,
    width: 0,
    zIndex: 9999,
    visibility: "hidden",
  })
  const [listMaxHeight, setListMaxHeight] = useState(288)

  const selectedDoctorIds = Array.isArray(value.doctorIds) ? value.doctorIds : []
  const selectedSet = useMemo(() => new Set(selectedDoctorIds), [selectedDoctorIds])

  const doctorsById = useMemo(() => {
    const map = new Map<string, DoctorOption>()
    for (const d of doctors) map.set(d.id, d)
    return map
  }, [doctors])

  useEffect(() => {
    let cancelled = false
    async function load() {
      setLoadingDoctors(true)
      setDoctorsLoadError(null)
      try {
        const localeParam = encodeURIComponent(doctorNameLocale)
        const res = await fetch(`/api/admin/doctors?locale=${localeParam}`, {
          cache: "no-store",
          credentials: "include",
        })
        const json = await res.json().catch(() => ({}))
        if (!res.ok || json?.success === false) {
          throw new Error(typeof json?.error === "string" ? json.error : "Failed to load doctors")
        }
        const list = Array.isArray(json?.doctors) ? json.doctors : []
        if (!cancelled) {
          setDoctors(
            list
              .filter((d: any) => d?.status === "published" && typeof d?.id === "string" && typeof d?.name === "string")
              .map((d: any) => ({ id: d.id, name: d.name, image: typeof d.image === "string" ? d.image : undefined }))
              .sort((a: DoctorOption, b: DoctorOption) => a.name.localeCompare(b.name)),
          )
        }
      } catch (e) {
        if (!cancelled) setDoctorsLoadError(e instanceof Error ? e.message : "Failed to load doctors")
      } finally {
        if (!cancelled) setLoadingDoctors(false)
      }
    }

    void load()
    return () => {
      cancelled = true
    }
  }, [doctorNameLocale])

  function updateDropdownPosition() {
    if (!triggerRef.current) return
    const rect = triggerRef.current.getBoundingClientRect()
    const gap = 8
    const searchHeaderHeight = 60
    const preferredListHeight = 288
    const spaceBelow = window.innerHeight - rect.bottom - gap
    const spaceAbove = rect.top - gap
    const openBelow = spaceBelow >= 160 || spaceBelow >= spaceAbove
    const availableListHeight = openBelow
      ? Math.max(120, spaceBelow - searchHeaderHeight - gap)
      : Math.max(120, spaceAbove - searchHeaderHeight - gap)
    const listHeight = Math.min(preferredListHeight, availableListHeight)
    const top = openBelow ? rect.bottom + gap : rect.top - gap - searchHeaderHeight - listHeight

    setListMaxHeight(listHeight)
    setDropdownStyle({
      position: "fixed",
      top,
      left: rect.left,
      width: rect.width,
      zIndex: 9999,
      visibility: "visible",
    })
  }

  useLayoutEffect(() => {
    if (!open) {
      setQuery("")
      return
    }
    updateDropdownPosition()
    window.addEventListener("resize", updateDropdownPosition)
    window.addEventListener("scroll", updateDropdownPosition, true)
    return () => {
      window.removeEventListener("resize", updateDropdownPosition)
      window.removeEventListener("scroll", updateDropdownPosition, true)
    }
  }, [open])

  function set<K extends keyof HospitalDoctorsSectionData>(key: K, val: HospitalDoctorsSectionData[K]) {
    onChange({ ...value, [key]: val })
  }

  function toggleDoctorId(id: string) {
    if (selectedSet.has(id)) {
      set("doctorIds", selectedDoctorIds.filter((x) => x !== id))
    } else {
      set("doctorIds", [...selectedDoctorIds, id])
    }
  }

  const filteredDoctors = useMemo(() => {
    const q = query.trim().toLowerCase()
    if (!q) return doctors
    return doctors.filter((d) => d.name.toLowerCase().includes(q))
  }, [doctors, query])

  const selectedDoctors = useMemo(() => {
    return selectedDoctorIds.map((id) => doctorsById.get(id) ?? { id, name: id })
  }, [selectedDoctorIds, doctorsById])

  return (
    <div className="flex flex-col gap-5">
      <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
        <div className="flex flex-col gap-1.5">
          <label className="text-xs font-bold text-foreground font-sans uppercase tracking-wider">Eyebrow</label>
          <input
            type="text"
            value={value.eyebrow}
            onChange={(e) => set("eyebrow", e.target.value)}
            placeholder="e.g. Our Specialists"
            className={inputClass}
          />
        </div>
        <div className="flex flex-col gap-1.5">
          <label className="text-xs font-bold text-foreground font-sans uppercase tracking-wider">Title</label>
          <input type="text" value={value.title} onChange={(e) => set("title", e.target.value)} placeholder="e.g. Meet Our Expert Doctors" className={inputClass} />
        </div>
      </div>

      {/* Doctors picker */}
      <div className="flex flex-col gap-1.5">
        <label className="text-xs font-bold text-foreground font-sans uppercase tracking-wider">Doctors</label>

        <div className="relative" ref={triggerRef}>
          <button
            type="button"
            onClick={() => {
              if (!open) {
                updateDropdownPosition()
                setOpen(true)
              } else {
                setOpen(false)
              }
            }}
            className="w-full bg-card border border-border rounded-xl px-4 py-2.5 text-sm text-foreground font-sans outline-none transition-colors flex items-center justify-between gap-3"
            style={{ boxShadow: "none" }}
            aria-haspopup="listbox"
            aria-expanded={open}
          >
            <span className={selectedDoctorIds.length ? "text-foreground" : "text-muted-foreground"}>
              {selectedDoctorIds.length ? `${selectedDoctorIds.length} doctor(s) selected` : "Select doctors..."}
            </span>
            <ChevronDown className={`w-4 h-4 text-muted-foreground transition-transform ${open ? "rotate-180" : ""}`} aria-hidden="true" />
          </button>

          {open ? (
            <>
              <div
                className="fixed inset-0"
                style={{ zIndex: 9998 }}
                onClick={() => setOpen(false)}
                aria-hidden="true"
              />

              <div
                style={dropdownStyle}
                className="bg-card border border-border rounded-xl shadow-xl overflow-hidden"
              >
                <div className="p-3 border-b border-border">
                  <div className="relative">
                    <Search className="w-4 h-4 absolute left-3 top-1/2 -translate-y-1/2 text-muted-foreground" aria-hidden="true" />
                    <input
                      type="text"
                      value={query}
                      onChange={(e) => setQuery(e.target.value)}
                      placeholder="Search doctor..."
                      className="w-full bg-card border border-border rounded-xl px-4 py-2.5 pl-10 pr-10 text-sm text-foreground font-sans placeholder:text-muted-foreground outline-none focus:ring-2 focus:ring-[#2BB673]/30 focus:border-[#2BB673] transition-colors"
                    />
                    {query.trim().length > 0 ? (
                      <button
                        type="button"
                        onClick={() => setQuery("")}
                        className="absolute right-3 top-1/2 -translate-y-1/2 p-1 rounded-md hover:bg-muted transition-colors"
                        aria-label="Clear search"
                      >
                        <X className="w-4 h-4 text-muted-foreground" aria-hidden="true" />
                      </button>
                    ) : null}
                  </div>
                </div>

                <div className="overflow-auto" style={{ maxHeight: listMaxHeight }}>
                  {loadingDoctors ? (
                    <div className="p-3 text-sm text-muted-foreground font-sans flex items-center gap-2">
                      <Loader2 className="w-4 h-4 animate-spin" aria-hidden="true" />
                      Loading doctors...
                    </div>
                  ) : doctorsLoadError ? (
                    <div className="p-3 text-sm text-red-500 font-sans">{doctorsLoadError}</div>
                  ) : filteredDoctors.length === 0 ? (
                    <div className="p-3 text-sm text-muted-foreground font-sans">No doctors found.</div>
                  ) : (
                    <div className="flex flex-col" role="listbox">
                      {filteredDoctors.map((doc) => {
                        const isSelected = selectedSet.has(doc.id)
                        return (
                          <button
                            key={doc.id}
                            type="button"
                            onClick={() => toggleDoctorId(doc.id)}
                            className={`w-full text-left px-4 py-2.5 flex items-center justify-between gap-3 hover:bg-muted transition-colors ${
                              isSelected ? "bg-accent" : ""
                            }`}
                          >
                            <span className="text-sm font-medium text-foreground truncate">{doc.name}</span>
                            {isSelected ? <Check className="w-4 h-4 text-[var(--brand-green)] shrink-0" aria-hidden="true" /> : null}
                          </button>
                        )
                      })}
                    </div>
                  )}
                </div>
              </div>
            </>
          ) : null}
        </div>

        {selectedDoctorIds.length > 0 ? (
          <div className="flex flex-wrap gap-1.5 pt-2">
            {selectedDoctors.map((doc) => (
              <span
                key={doc.id}
                className="inline-flex items-center gap-1 px-2.5 py-1 rounded-lg text-xs font-medium font-sans"
                style={{ background: "rgba(29,45,104,0.08)", color: "var(--brand-navy)" }}
              >
                {doc.name}
                <button
                  type="button"
                  onClick={() => toggleDoctorId(doc.id)}
                  aria-label={`Remove doctor ${doc.name}`}
                  className="ml-0.5 hover:opacity-70 transition-opacity"
                >
                  <X className="w-3.5 h-3.5" aria-hidden="true" />
                </button>
              </span>
            ))}
          </div>
        ) : null}
      </div>

      <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
        <div className="flex flex-col gap-1.5">
          <label className="text-xs font-bold text-foreground font-sans uppercase tracking-wider">Primary Button Text</label>
          <input
            type="text"
            value={value.primaryButtonText}
            onChange={(e) => set("primaryButtonText", e.target.value)}
            placeholder="e.g. View All Doctors"
            className={inputClass}
          />
        </div>
        <div className="flex flex-col gap-1.5">
          <label className="text-xs font-bold text-foreground font-sans uppercase tracking-wider">Primary Button Link</label>
          <input
            type="text"
            value={value.primaryButtonLink}
            onChange={(e) => set("primaryButtonLink", e.target.value)}
            placeholder="e.g. /doctors"
            className={inputClass}
          />
        </div>
      </div>

      <div
        className="flex items-center gap-3 px-4 py-3 rounded-xl text-sm font-sans"
        style={{ background: "rgba(29,45,104,0.05)", borderLeft: "3px solid var(--brand-navy)", color: "var(--brand-navy)" }}
      >
        <span className="w-2 h-2 rounded-full shrink-0" style={{ background: "var(--brand-navy)" }} aria-hidden="true" />
        <span>
          This hospital&apos;s doctors section will use the selected doctors from the Doctors database (search by name).
        </span>
      </div>
    </div>
  )
}
