"use client"

import { ImagePlus, X, Star, Globe } from "lucide-react"
import { useRef, useState } from "react"
import { MEDIA_FILE_BASE } from "@/lib/media-manager/file-names"
import { stageImage } from "@/lib/media-manager/stage"
import type { StagedImage } from "@/lib/media-manager/types"

export interface DoctorBasicInfoData {
  name: string
  image: string
  imagePublicId: string
  rating: number | ""
  reviewCount: number | ""
  description: string
  experienceYears: number | ""
  casesCount: string
  successRate: string
  nationalities: string
  languages: string[]
}

interface Props {
  value: DoctorBasicInfoData
  onChange: (value: DoctorBasicInfoData) => void
  getDoctorName?: () => string
  onStageProfileImage?: (staged: StagedImage) => void
  onClearStagedProfileImage?: () => void
  sharedFieldsLocked?: boolean
  invalidFields?: {
    name?: boolean
    image?: boolean
    description?: boolean
    rating?: boolean
    reviewCount?: boolean
    experienceYears?: boolean
    casesCount?: boolean
    successRate?: boolean
    nationalities?: boolean
    languages?: boolean
  }
}

function DoctorImageUploader({
  value,
  onChange,
  getDoctorName,
  onStageProfileImage,
  onClearStagedProfileImage,
  invalid = false,
  disabled = false,
}: {
  value: string
  imagePublicId: string
  onChange: (url: string, publicId: string) => void
  getDoctorName?: () => string
  onStageProfileImage?: (staged: StagedImage) => void
  onClearStagedProfileImage?: () => void
  invalid?: boolean
  disabled?: boolean
}) {
  const inputRef = useRef<HTMLInputElement>(null)
  const [dragOver, setDragOver] = useState(false)
  const [error, setError] = useState<string | null>(null)

  function handleFile(file: File) {
    if (disabled) return
    setError(null)
    if (!file.type.startsWith("image/")) {
      setError("Please upload a valid image file.")
      return
    }
    if (file.size > 2 * 1024 * 1024) {
      setError("Image size must be 2 MB or less.")
      return
    }
    const doctorName = getDoctorName?.().trim() ?? ""
    if (!doctorName) {
      setError("Please enter the doctor name before selecting an image.")
      return
    }
    try {
      const staged = stageImage(file, { fileBaseName: MEDIA_FILE_BASE.doctorPhoto })
      onStageProfileImage?.(staged)
      onChange(staged.previewUrl, "")
    } catch {
      setError("Failed to prepare image.")
    }
  }

  return (
    <div className="flex flex-col gap-1.5">
      <label className="text-xs font-bold text-foreground font-sans uppercase tracking-wider">
        Doctor Photo
      </label>
      {value ? (
        <div className={`relative w-32 h-32 rounded-2xl overflow-hidden border bg-card ${invalid ? "border-red-500" : "border-border"}`}>
          {/* eslint-disable-next-line @next/next/no-img-element */}
          <img src={value} alt="Doctor preview" className="w-full h-full object-cover" />
          <button
            type="button"
            onClick={() => {
              onClearStagedProfileImage?.()
              onChange("", "")
            }}
            disabled={disabled}
            className="absolute top-1.5 right-1.5 w-7 h-7 rounded-lg bg-black/60 flex items-center justify-center text-white hover:bg-black/80 transition-colors cursor-pointer"
            aria-label="Remove image"
          >
            <X className="w-3.5 h-3.5" aria-hidden="true" />
          </button>
        </div>
      ) : (
        <div
          role="button"
          tabIndex={0}
          onClick={() => !disabled && inputRef.current?.click()}
          onKeyDown={(e) => e.key === "Enter" && !disabled && inputRef.current?.click()}
          onDragOver={(e) => { e.preventDefault(); setDragOver(true) }}
          onDragLeave={() => setDragOver(false)}
          onDrop={(e) => {
            e.preventDefault()
            setDragOver(false)
            const file = e.dataTransfer.files[0]
            if (file) handleFile(file)
          }}
          className="flex flex-col items-center justify-center gap-2 w-32 h-32 rounded-2xl border-2 border-dashed cursor-pointer transition-all"
          style={{
            borderColor: invalid ? "#ef4444" : dragOver ? "var(--brand-green)" : "var(--border)",
            background: dragOver ? "rgba(43,182,115,0.04)" : "var(--card)",
          }}
          aria-label="Upload doctor photo"
        >
          <>
              <div
                className="w-10 h-10 rounded-xl flex items-center justify-center"
                style={{ background: "rgba(43,182,115,0.10)" }}
              >
                <ImagePlus className="w-5 h-5" style={{ color: "var(--brand-green)" }} aria-hidden="true" />
              </div>
              <p className="text-[10px] text-muted-foreground font-sans text-center leading-tight">
                Click or drag
                <br />
                to add (saved on submit)
              </p>
          </>
        </div>
      )}
      {error && (
        <p className="text-xs font-sans text-red-500" role="alert">{error}</p>
      )}
      {invalid && !value && (
        <p className="text-xs font-sans text-red-500">Doctor photo is required.</p>
      )}
      <input
        ref={inputRef}
        type="file"
        accept="image/*"
        className="sr-only"
        aria-hidden="true"
        onChange={(e) => {
          if (disabled) return
          const file = e.target.files?.[0]
          if (file) handleFile(file)
          e.target.value = ""
        }}
      />
    </div>
  )
}

function NumericInput({
  id,
  label,
  placeholder,
  value,
  onChange,
  min = 0,
  max,
  suffix,
  invalid = false,
  disabled = false,
}: {
  id: string
  label: string
  placeholder: string
  value: number | ""
  onChange: (v: number | "") => void
  min?: number
  max?: number
  suffix?: string
  invalid?: boolean
  disabled?: boolean
}) {
  const inputValue =
    value === "" || typeof value !== "number" || !Number.isFinite(value) ? "" : value

  return (
    <div className="flex flex-col gap-1.5">
      <label htmlFor={id} className="text-xs font-bold text-foreground font-sans uppercase tracking-wider">
        {label}
      </label>
      <div className="relative">
        <input
          id={id}
          type="number"
          min={min}
          max={max}
          value={inputValue}
          disabled={disabled}
          onChange={(e) => {
            const v = e.target.value
            if (v === "") { onChange(""); return }
            const n = Number(v)
            if (!Number.isNaN(n)) onChange(n)
          }}
          placeholder={placeholder}
          className={`w-full bg-card border rounded-xl px-3 py-2.5 text-sm text-foreground font-sans placeholder:text-muted-foreground outline-none transition-colors ${
            invalid
              ? "border-red-500 focus:ring-2 focus:ring-red-200 focus:border-red-500"
              : "border-border focus:ring-2 focus:ring-[#2BB673]/30 focus:border-[#2BB673]"
          }`}
          style={{ paddingRight: suffix ? "2.75rem" : undefined }}
        />
        {suffix && (
          <span className="absolute right-3 top-1/2 -translate-y-1/2 text-xs text-muted-foreground font-sans pointer-events-none">
            {suffix}
          </span>
        )}
      </div>
    </div>
  )
}

export function DoctorBasicInfo({
  value,
  onChange,
  getDoctorName,
  onStageProfileImage,
  onClearStagedProfileImage,
  invalidFields,
  sharedFieldsLocked = false,
}: Props) {
  function set<K extends keyof DoctorBasicInfoData>(key: K, val: DoctorBasicInfoData[K]) {
    onChange({ ...value, [key]: val })
  }

  return (
    <div className="flex flex-col gap-5">
      {/* Image + Name row */}
      <div className="flex flex-col sm:flex-row gap-5 items-start">
        <DoctorImageUploader
          value={value.image}
          imagePublicId={value.imagePublicId}
          getDoctorName={getDoctorName}
          onStageProfileImage={onStageProfileImage}
          onClearStagedProfileImage={onClearStagedProfileImage}
          invalid={invalidFields?.image}
          disabled={sharedFieldsLocked}
          onChange={(url, publicId) => {
            onChange({
              ...value,
              image: url,
              imagePublicId: publicId,
            })
          }}
        />

        <div className="flex-1 flex flex-col gap-4 w-full">
          {/* Doctor name */}
          <div className="flex flex-col gap-1.5">
            <label htmlFor="doctor-name" className="text-xs font-bold text-foreground font-sans uppercase tracking-wider">
              Doctor Name
            </label>
            <input
              id="doctor-name"
              type="text"
              value={value.name}
              onChange={(e) => set("name", e.target.value)}
              placeholder="e.g. Dr. Ahmed Hassan"
              className={`w-full bg-card border rounded-xl px-3 py-2.5 text-sm text-foreground font-sans placeholder:text-muted-foreground outline-none transition-colors ${
                invalidFields?.name
                  ? "border-red-500 focus:ring-2 focus:ring-red-200 focus:border-red-500"
                  : "border-border focus:ring-2 focus:ring-[#2BB673]/30 focus:border-[#2BB673]"
              }`}
            />
            {invalidFields?.name && (
              <p className="text-xs font-sans text-red-500">Doctor name is required.</p>
            )}
          </div>

          {/* Rating + Review count */}
          <div className="grid grid-cols-2 gap-3">
            <div className="flex flex-col gap-1.5">
              <label htmlFor="doctor-rating" className="text-xs font-bold text-foreground font-sans uppercase tracking-wider flex items-center gap-1">
                <Star className="w-3 h-3" style={{ color: "var(--brand-green)" }} aria-hidden="true" />
                Rating
              </label>
              <input
                id="doctor-rating"
                type="number"
                min={0}
                max={5}
                step={0.1}
                value={
                  value.rating === "" || !Number.isFinite(value.rating) ? "" : value.rating
                }
                disabled={sharedFieldsLocked}
                onChange={(e) => {
                  const v = e.target.value
                  if (v === "") { set("rating", ""); return }
                  const n = Number(v)
                  if (!Number.isNaN(n)) set("rating", Math.min(5, Math.max(0, n)))
                }}
                placeholder="e.g. 4.9"
                className={`w-full bg-card border rounded-xl px-3 py-2.5 text-sm text-foreground font-sans placeholder:text-muted-foreground outline-none transition-colors ${
                  invalidFields?.rating
                    ? "border-red-500 focus:ring-2 focus:ring-red-200 focus:border-red-500"
                    : "border-border focus:ring-2 focus:ring-[#2BB673]/30 focus:border-[#2BB673]"
                }`}
              />
            </div>
            <NumericInput
              id="doctor-review-count"
              label="Review Count"
              placeholder="e.g. 320"
              value={value.reviewCount}
              onChange={(v) => set("reviewCount", v)}
              min={0}
              invalid={invalidFields?.reviewCount}
              disabled={sharedFieldsLocked}
            />
          </div>
        </div>
      </div>

      {/* Description */}
      <div className="flex flex-col gap-1.5">
        <label htmlFor="doctor-description" className="text-xs font-bold text-foreground font-sans uppercase tracking-wider">
          Description
        </label>
        <textarea
          id="doctor-description"
          value={value.description}
          onChange={(e) => set("description", e.target.value)}
          placeholder="Brief description of the doctor's expertise and background..."
          rows={3}
          className={`w-full bg-card border rounded-xl px-3 py-2.5 text-sm text-foreground font-sans placeholder:text-muted-foreground outline-none transition-colors resize-none leading-relaxed ${
            invalidFields?.description
              ? "border-red-500 focus:ring-2 focus:ring-red-200 focus:border-red-500"
              : "border-border focus:ring-2 focus:ring-[#2BB673]/30 focus:border-[#2BB673]"
          }`}
        />
        {invalidFields?.description && (
          <p className="text-xs font-sans text-red-500">Description is required.</p>
        )}
      </div>

      {/* Stats grid */}
      <div className="grid grid-cols-2 md:grid-cols-4 gap-3">
        <NumericInput
          id="doctor-experience"
          label="Experience (Years)"
          placeholder="e.g. 15"
          value={value.experienceYears}
          onChange={(v) => set("experienceYears", v)}
          min={0}
          suffix="yrs"
          invalid={invalidFields?.experienceYears}
          disabled={sharedFieldsLocked}
        />
        <NumericInput
          id="doctor-cases"
          label="Cases Count"
          placeholder="e.g. 5000"
          value={value.casesCount ? Number(value.casesCount) : ""}
          onChange={(v) => set("casesCount", v === "" ? "" : String(v))}
          min={0}
          invalid={invalidFields?.casesCount}
          disabled={sharedFieldsLocked}
        />
        <NumericInput
          id="doctor-success-rate"
          label="Success Rate"
          placeholder="e.g. 98"
          value={value.successRate ? Number(value.successRate) : ""}
          onChange={(v) => set("successRate", v === "" ? "" : String(v))}
          min={0}
          max={100}
          suffix="%"
          invalid={invalidFields?.successRate}
          disabled={sharedFieldsLocked}
        />
        <div className="flex flex-col gap-1.5">
          <label htmlFor="doctor-nationalities" className="text-xs font-bold text-foreground font-sans uppercase tracking-wider">
            Nationalities
          </label>
          <input
            id="doctor-nationalities"
            type="text"
            value={value.nationalities}
            onChange={(e) => set("nationalities", e.target.value)}
            disabled={sharedFieldsLocked}
            placeholder="e.g. 50+"
            className={`w-full bg-card border rounded-xl px-3 py-2.5 text-sm text-foreground font-sans placeholder:text-muted-foreground outline-none transition-colors ${
              invalidFields?.nationalities
                ? "border-red-500 focus:ring-2 focus:ring-red-200 focus:border-red-500"
                : "border-border focus:ring-2 focus:ring-[#2BB673]/30 focus:border-[#2BB673]"
            }`}
          />
        </div>
      </div>

      {/* Languages — tag-style input */}
      <LanguagesTagInput
        value={value.languages}
        onChange={(langs) => set("languages", langs)}
        invalid={invalidFields?.languages}
      />
    </div>
  )
}

// ─── Languages tag input ──────────────────────────────────────────────────────

function LanguagesTagInput({
  value,
  onChange,
  invalid = false,
}: {
  value: string[]
  onChange: (langs: string[]) => void
  invalid?: boolean
}) {
  const [input, setInput] = useState("")

  function addLanguage() {
    const parts = input
      .split(/[,;]+/)
      .map((p) => p.trim())
      .filter((p) => p.length > 0)
    if (parts.length === 0) return
    const existing = new Set(value.map((l) => l.toLowerCase()))
    const toAdd = parts.filter((p) => !existing.has(p.toLowerCase()))
    if (toAdd.length > 0) onChange([...value, ...toAdd])
    setInput("")
  }

  function removeLanguage(lang: string) {
    onChange(value.filter((l) => l !== lang))
  }

  function handleKeyDown(e: React.KeyboardEvent<HTMLInputElement>) {
    if (e.key === "Enter") { e.preventDefault(); addLanguage(); return }
    if (e.key === "," || e.key === ";") { e.preventDefault(); addLanguage() }
  }

  return (
    <div className="flex flex-col gap-2">
      <div className="flex flex-col gap-1.5">
        <label
          htmlFor="doctor-languages"
          className="text-xs font-bold text-foreground font-sans uppercase tracking-wider"
        >
          Languages{" "}
          <span className="text-muted-foreground normal-case font-normal tracking-normal">
            (press Enter or comma to add)
          </span>
        </label>
      </div>
      {value.length > 0 && (
        <div className="flex flex-wrap gap-1.5">
          {value.map((lang) => (
            <span
              key={lang}
              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)" }}
            >
              <Globe className="w-3 h-3" aria-hidden="true" />
              {lang}
              <button
                type="button"
                onClick={() => removeLanguage(lang)}
                aria-label={`Remove language ${lang}`}
                className="ml-0.5 hover:opacity-70 transition-opacity"
              >
                <X className="w-3 h-3" aria-hidden="true" />
              </button>
            </span>
          ))}
        </div>
      )}
      <div className="flex gap-2">
        <input
          id="doctor-languages"
          type="text"
          value={input}
          onChange={(e) => setInput(e.target.value)}
          onKeyDown={handleKeyDown}
          onBlur={() => addLanguage()}
          placeholder="e.g. Arabic, English, Turkish"
          className={`flex-1 bg-card border rounded-xl px-4 py-2.5 text-sm text-foreground font-sans placeholder:text-muted-foreground outline-none transition-colors ${
            invalid
              ? "border-red-500 focus:ring-2 focus:ring-red-200 focus:border-red-500"
              : "border-border focus:ring-2 focus:ring-[#2BB673]/30 focus:border-[#2BB673]"
          }`}
        />
        <button
          type="button"
          onClick={() => addLanguage()}
          className="px-4 py-2.5 rounded-xl text-sm font-semibold font-sans transition-colors border border-border hover:bg-accent cursor-pointer"
        >
          Add
        </button>
      </div>
      {invalid && (
        <p className="text-xs font-sans text-red-500">Please add at least one language.</p>
      )}
    </div>
  )
}
