// src/components/ui/index.tsx
"use client";
import React from "react";
import {
  cn,
  getLabel,
  LEAD_STATUS_LABELS,
  LEAD_STATUS_LABELS_AR,
  LEAD_STATUS_COLORS,
  TASK_PRIORITY_LABELS,
  TASK_PRIORITY_LABELS_AR,
  TICKET_PRIORITY_LABELS,
  TICKET_PRIORITY_LABELS_AR,
} from "@/lib/utils";
import { useLanguage } from "@/i18n/LanguageContext";
import { AlertTriangle, Check, ChevronDown, HelpCircle, Loader2, X } from "lucide-react";

/** Shared validation message — used by Input, Select, Textarea, and custom forms */
export function FieldError({ id, message }: { id: string; message: string }) {
  return (
    <p id={id} role="alert" className="text-xs text-destructive leading-snug">
      {message}
    </p>
  );
}

function FieldHint({ id, children }: { id: string; children: React.ReactNode }) {
  return (
    <p id={id} className="text-xs text-muted-foreground leading-relaxed">
      {children}
    </p>
  );
}

// ─── Button ───────────────────────────────────────────────────────────────────
export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
  variant?: "primary" | "secondary" | "outline" | "ghost" | "destructive" | "link";
  size?: "sm" | "md" | "lg" | "icon";
  loading?: boolean;
  children: React.ReactNode;
}

export function Button({
  variant = "primary",
  size = "md",
  loading,
  disabled,
  className,
  children,
  ...props
}: ButtonProps) {
  const base = "inline-flex items-center justify-center gap-2 font-medium rounded-lg transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:opacity-50 disabled:pointer-events-none whitespace-nowrap";
  const variants = {
    primary: "bg-primary text-primary-foreground hover:bg-primary/90 shadow-sm",
    secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
    outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
    ghost: "hover:bg-accent hover:text-accent-foreground",
    destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90 shadow-sm",
    link: "text-primary underline-offset-4 hover:underline",
  };
  const sizes = {
    sm: "h-8 px-3 text-xs",
    md: "h-9 px-4 text-sm",
    lg: "h-10 px-6 text-sm",
    icon: "h-9 w-9",
  };

  return (
    <button
      className={cn(base, variants[variant], sizes[size], className)}
      disabled={disabled || loading}
      {...props}
    >
      {loading && <Loader2 className="w-4 h-4 animate-spin" />}
      {children}
    </button>
  );
}

// ─── Input ────────────────────────────────────────────────────────────────────
export interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
  label?: string;
  error?: string;
  hint?: string;
  startIcon?: React.ReactNode;
  endIcon?: React.ReactNode;
}

function isDateLikeType(t: string | undefined): boolean {
  return (
    t === "date" ||
    t === "datetime-local" ||
    t === "month" ||
    t === "week" ||
    t === "time"
  );
}

export const Input = React.forwardRef<HTMLInputElement, InputProps>(
  ({ label, error, hint, startIcon, endIcon, className, id, required, type, ...props }, ref) => {
    const inputId = id ?? label?.toLowerCase().replace(/\s+/g, "-");
    const errId = `${inputId}-error`;
    const hintId = `${inputId}-hint`;
    const dateLike = isDateLikeType(type);
    return (
      <div className="space-y-2">
        {label && (
          <label
            htmlFor={inputId}
            className={cn(
              "text-sm font-medium transition-colors",
              error ? "text-destructive/90" : "text-foreground"
            )}
          >
            {label}
            {required && <span className="text-destructive ms-1">*</span>}
          </label>
        )}
        <div className="relative">
          {startIcon && (
            <span
              className={cn(
                "absolute start-3 top-1/2 -translate-y-1/2 pointer-events-none transition-colors",
                error ? "text-destructive/70" : "text-muted-foreground"
              )}
            >
              {startIcon}
            </span>
          )}
          <input
            ref={ref}
            id={inputId}
            type={type}
            className={cn(
              "w-full h-10 rounded-lg border bg-background text-sm placeholder:text-muted-foreground transition-[box-shadow,border-color,background-color] duration-200",
              "focus:outline-none focus:ring-2 focus:ring-offset-0",
              error
                ? "border-destructive/80 bg-destructive/[0.04] ring-2 ring-destructive/15 focus:border-destructive focus:ring-destructive/25 placeholder:text-destructive/40"
                : "border-input focus:ring-primary/25 focus:border-primary/40",
              dateLike && "crm-date-input min-w-[10.5rem]",
              startIcon ? "ps-9" : "ps-3",
              endIcon ? "pe-9" : "pe-3",
              className
            )}
            {...props}
            aria-required={required ? true : undefined}
            aria-invalid={error ? true : undefined}
            aria-describedby={error ? errId : hint ? hintId : undefined}
          />
          {endIcon && (
            <span className="absolute end-3 top-1/2 -translate-y-1/2 text-muted-foreground pointer-events-none">
              {endIcon}
            </span>
          )}
        </div>
        {error && <FieldError id={errId} message={error} />}
        {hint && !error && <FieldHint id={hintId}>{hint}</FieldHint>}
      </div>
    );
  }
);
Input.displayName = "Input";

// ─── Select (custom dropdown; hidden native <select> for React Hook Form) ─────
export interface SelectOption { value: string; label: string; }
export interface SelectProps extends Omit<React.SelectHTMLAttributes<HTMLSelectElement>, "children"> {
  label?: string;
  error?: string;
  hint?: string;
  options: SelectOption[];
  placeholder?: string;
}

export const Select = React.forwardRef<HTMLSelectElement, SelectProps>(
  (
    {
      label,
      error,
      hint,
      options,
      placeholder,
      className,
      id,
      required,
      disabled,
      onChange,
      onBlur,
      value: valueProp,
      defaultValue,
      ...rest
    },
    ref
  ) => {
    const inputId = id ?? label?.toLowerCase().replace(/\s+/g, "-");
    const listboxId = `${inputId}-listbox`;
    const errId = `${inputId}-error`;
    const hintId = `${inputId}-hint`;
    const hiddenRef = React.useRef<HTMLSelectElement | null>(null);
    const containerRef = React.useRef<HTMLDivElement | null>(null);
    const [open, setOpen] = React.useState(false);

    const isControlled = valueProp !== undefined;
    const [uncontrolledValue, setUncontrolledValue] = React.useState(() =>
      defaultValue !== undefined ? String(defaultValue) : ""
    );

    React.useEffect(() => {
      if (defaultValue === undefined) return;
      setUncontrolledValue(String(defaultValue));
    }, [defaultValue]);

    const setHiddenRef = React.useCallback(
      (node: HTMLSelectElement | null) => {
        hiddenRef.current = node;
        if (typeof ref === "function") ref(node);
        else if (ref) (ref as React.MutableRefObject<HTMLSelectElement | null>).current = node;
      },
      [ref]
    );

    React.useLayoutEffect(() => {
      const el = hiddenRef.current;
      if (!el || isControlled) return;
      setUncontrolledValue(el.value);
    }, [isControlled]);

    const currentValue = isControlled ? String(valueProp ?? "") : uncontrolledValue;

    React.useEffect(() => {
      const onDoc = (e: MouseEvent) => {
        if (!containerRef.current?.contains(e.target as Node)) setOpen(false);
      };
      const onKey = (e: KeyboardEvent) => {
        if (e.key === "Escape") setOpen(false);
      };
      document.addEventListener("mousedown", onDoc);
      document.addEventListener("keydown", onKey);
      return () => {
        document.removeEventListener("mousedown", onDoc);
        document.removeEventListener("keydown", onKey);
      };
    }, []);

    const selectedLabel = options.find((o) => o.value === currentValue)?.label;
    const showPlaceholderStyle = !selectedLabel && currentValue === "" && !!placeholder;
    const displayText = showPlaceholderStyle
      ? placeholder!
      : selectedLabel ?? (currentValue || "—");

    const triggerClasses = cn(
      "flex w-full h-10 items-center justify-between gap-2 rounded-lg border bg-background px-3 text-start text-sm transition-[box-shadow,border-color,background-color] duration-200",
      "focus:outline-none focus:ring-2 focus:ring-offset-0",
      error
        ? "border-destructive/80 bg-destructive/[0.04] ring-2 ring-destructive/15 focus:border-destructive focus:ring-destructive/25"
        : "border-input focus:ring-primary/25 focus:border-primary/40",
      disabled && "cursor-not-allowed opacity-60",
      showPlaceholderStyle && "text-muted-foreground",
      className
    );

    const pick = (val: string) => {
      const el = hiddenRef.current;
      if (!el || disabled) return;
      el.value = val;
      if (!isControlled) setUncontrolledValue(val);
      const ev = {
        target: el,
        currentTarget: el,
      } as React.ChangeEvent<HTMLSelectElement>;
      onChange?.(ev);
      setOpen(false);
      onBlur?.({
        target: el,
        currentTarget: el,
      } as React.FocusEvent<HTMLSelectElement>);
    };

    const handleHiddenChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
      if (!isControlled) setUncontrolledValue(e.target.value);
      onChange?.(e);
    };

    const handleTriggerBlur = (e: React.FocusEvent<HTMLButtonElement>) => {
      requestAnimationFrame(() => {
        if (!containerRef.current?.contains(document.activeElement)) {
          const el = hiddenRef.current;
          if (el) {
            onBlur?.({
              target: el,
              currentTarget: el,
            } as React.FocusEvent<HTMLSelectElement>);
          }
        }
      });
    };

    return (
      <div className="space-y-2">
        {label && (
          <label
            id={`${inputId}-label`}
            htmlFor={inputId}
            className={cn(
              "text-sm font-medium transition-colors",
              error ? "text-destructive/90" : "text-foreground"
            )}
          >
            {label}
            {required && <span className="text-destructive ms-1">*</span>}
          </label>
        )}
        <div ref={containerRef} className="relative">
          <select
            ref={setHiddenRef}
            {...rest}
            id={`${inputId}-native`}
            {...(isControlled ? { value: valueProp ?? "" } : { defaultValue })}
            disabled={disabled}
            onChange={handleHiddenChange}
            className="sr-only"
            tabIndex={-1}
            aria-hidden
          >
            {placeholder && <option value="">{placeholder}</option>}
            {options.map((opt) => (
              <option key={opt.value} value={opt.value}>
                {opt.label}
              </option>
            ))}
          </select>

          <button
            type="button"
            role="combobox"
            aria-autocomplete="list"
            id={inputId}
            disabled={disabled}
            className={triggerClasses}
            aria-haspopup="listbox"
            aria-expanded={open}
            aria-controls={listboxId}
            aria-labelledby={label ? `${inputId}-label` : undefined}
            aria-invalid={error ? true : undefined}
            aria-describedby={
              [error ? errId : undefined, hint && !error ? hintId : undefined].filter(Boolean).join(" ") ||
              undefined
            }
            aria-required={required ? true : undefined}
            onClick={() => !disabled && setOpen((o) => !o)}
            onBlur={handleTriggerBlur}
          >
            <span className="min-w-0 flex-1 truncate">{displayText}</span>
            <ChevronDown
              className={cn("h-4 w-4 shrink-0 text-muted-foreground transition-transform", open && "rotate-180")}
              aria-hidden
            />
          </button>

          {open && !disabled && (
            <ul
              id={listboxId}
              role="listbox"
              className={cn(
                "absolute start-0 end-0 top-full z-50 mt-1 max-h-60 overflow-auto rounded-lg border border-border bg-popover py-1 shadow-lg",
                "animate-fade-in"
              )}
            >
              {placeholder && (
                <li
                  role="option"
                  aria-selected={currentValue === ""}
                  className={cn(
                    "cursor-pointer px-3 py-2 text-sm text-muted-foreground hover:bg-accent",
                    currentValue === "" && "bg-accent/80"
                  )}
                  onMouseDown={(e) => e.preventDefault()}
                  onClick={() => pick("")}
                >
                  {placeholder}
                </li>
              )}
              {options.map((opt) => {
                const isSelected = opt.value === currentValue;
                return (
                  <li
                    key={opt.value}
                    role="option"
                    aria-selected={isSelected}
                    className={cn(
                      "flex cursor-pointer items-center justify-between gap-2 px-3 py-2 text-sm text-foreground hover:bg-accent",
                      isSelected && "bg-primary/10 font-medium text-primary"
                    )}
                    onMouseDown={(e) => e.preventDefault()}
                    onClick={() => pick(opt.value)}
                  >
                    <span className="min-w-0 truncate">{opt.label}</span>
                    {isSelected && <Check className="h-4 w-4 shrink-0 text-primary" aria-hidden />}
                  </li>
                );
              })}
            </ul>
          )}
        </div>
        {error && <FieldError id={errId} message={error} />}
        {hint && !error && <FieldHint id={hintId}>{hint}</FieldHint>}
      </div>
    );
  }
);
Select.displayName = "Select";

// ─── Textarea ─────────────────────────────────────────────────────────────────
export interface TextareaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {
  label?: string;
  error?: string;
  hint?: string;
}

export const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
  ({ label, error, hint, className, id, rows, required, ...props }, ref) => {
    const inputId = id ?? label?.toLowerCase().replace(/\s+/g, "-");
    const errId = `${inputId}-error`;
    const hintId = `${inputId}-hint`;
    return (
      <div className="space-y-2">
        {label && (
          <label
            htmlFor={inputId}
            className={cn(
              "text-sm font-medium transition-colors",
              error ? "text-destructive/90" : "text-foreground"
            )}
          >
            {label}
            {required && <span className="text-destructive ms-1">*</span>}
          </label>
        )}
        <textarea
          ref={ref}
          id={inputId}
          className={cn(
            "w-full rounded-lg border bg-background text-sm p-3 placeholder:text-muted-foreground resize-none min-h-[88px] transition-[box-shadow,border-color,background-color] duration-200",
            "focus:outline-none focus:ring-2 focus:ring-offset-0",
            error
              ? "border-destructive/80 bg-destructive/[0.04] ring-2 ring-destructive/15 focus:border-destructive focus:ring-destructive/25 placeholder:text-destructive/40"
              : "border-input focus:ring-primary/25 focus:border-primary/40",
            className
          )}
          rows={rows ?? 3}
          {...props}
          aria-required={required ? true : undefined}
          aria-invalid={error ? true : undefined}
          aria-describedby={error ? errId : hint ? hintId : undefined}
        />
        {error && <FieldError id={errId} message={error} />}
        {hint && !error && <FieldHint id={hintId}>{hint}</FieldHint>}
      </div>
    );
  }
);
Textarea.displayName = "Textarea";

// ─── Card ─────────────────────────────────────────────────────────────────────
export function Card({ className, children, ...props }: React.HTMLAttributes<HTMLDivElement>) {
  return (
    <div className={cn("bg-card border border-border rounded-xl shadow-sm", className)} {...props}>
      {children}
    </div>
  );
}

export function CardHeader({ className, children }: React.HTMLAttributes<HTMLDivElement>) {
  return <div className={cn("px-6 py-4 border-b border-border", className)}>{children}</div>;
}

export function CardTitle({ className, children }: React.HTMLAttributes<HTMLHeadingElement>) {
  return <h3 className={cn("text-base font-semibold text-foreground", className)}>{children}</h3>;
}

export function CardContent({ className, children }: React.HTMLAttributes<HTMLDivElement>) {
  return <div className={cn("p-6", className)}>{children}</div>;
}

// ─── Badge ────────────────────────────────────────────────────────────────────
export interface BadgeProps extends React.HTMLAttributes<HTMLSpanElement> {
  variant?: "default" | "secondary" | "destructive" | "outline" | "success" | "warning";
}

export function Badge({ variant = "default", className, children, ...props }: BadgeProps) {
  const variants = {
    default: "bg-primary/10 text-primary",
    secondary: "bg-secondary text-secondary-foreground",
    destructive: "bg-destructive/10 text-destructive",
    outline: "border border-border text-foreground",
    success: "bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400",
    warning: "bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-400",
  };
  return (
    <span
      className={cn("inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium", variants[variant], className)}
      {...props}
    >
      {children}
    </span>
  );
}

// ─── Modal / Dialog ───────────────────────────────────────────────────────────
export interface ModalProps {
  open: boolean;
  onClose: () => void;
  title?: string;
  description?: string;
  children: React.ReactNode;
  size?: "sm" | "md" | "lg" | "xl";
}

const modalSizes = { sm: "max-w-sm", md: "max-w-md", lg: "max-w-lg", xl: "max-w-2xl" };

export function Modal({ open, onClose, title, description, children, size = "md" }: ModalProps) {
  if (!open) return null;
  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center p-4">
      <div className="absolute inset-0 bg-black/50 backdrop-blur-sm" onClick={onClose} />
      <div className={cn(
        "relative bg-card border border-border rounded-xl shadow-xl w-full animate-fade-in max-h-[90vh] flex flex-col",
        modalSizes[size]
      )}>
        {(title || description) && (
          <div className="px-6 py-4 border-b border-border flex items-start justify-between gap-4 flex-shrink-0">
            <div>
              {title && <h2 className="text-base font-semibold text-foreground">{title}</h2>}
              {description && <p className="text-sm text-muted-foreground mt-0.5">{description}</p>}
            </div>
            <button onClick={onClose} className="text-muted-foreground hover:text-foreground transition-colors flex-shrink-0">
              <X className="w-5 h-5" />
            </button>
          </div>
        )}
        <div className="flex-1 overflow-y-auto">{children}</div>
      </div>
    </div>
  );
}

// ─── Confirm Dialog ───────────────────────────────────────────────────────────
export interface ConfirmDialogProps {
  open: boolean;
  onClose: () => void;
  onConfirm: () => void;
  title?: string;
  description?: string;
  confirmLabel?: string;
  /** Defaults to `common.cancel` via i18n */
  cancelLabel?: string;
  isLoading?: boolean;
  variant?: "destructive" | "primary";
}

export function ConfirmDialog({
  open,
  onClose,
  onConfirm,
  title = "Are you sure?",
  description = "This action cannot be undone.",
  confirmLabel = "Confirm",
  cancelLabel: cancelLabelProp,
  isLoading,
  variant = "destructive",
}: ConfirmDialogProps) {
  const { t } = useLanguage();
  const cancelText = cancelLabelProp ?? t("common.cancel");
  const Icon = variant === "destructive" ? AlertTriangle : HelpCircle;
  const iconRing =
    variant === "destructive"
      ? "bg-destructive/15 text-destructive ring-[10px] ring-destructive/[0.08]"
      : "bg-primary/15 text-primary ring-[10px] ring-primary/[0.08]";

  if (!open) return null;

  return (
    <div
      className="fixed inset-0 z-50 flex items-center justify-center p-4"
      role="dialog"
      aria-modal="true"
      aria-labelledby="confirm-dialog-title"
      aria-describedby={description ? "confirm-dialog-desc" : undefined}
    >
      <div
        className="absolute inset-0 bg-black/55 backdrop-blur-[2px] animate-fade-in"
        onClick={onClose}
        aria-hidden
      />
      <div
        className={cn(
          "relative w-full max-w-[420px] overflow-hidden rounded-2xl border border-border/90 bg-card shadow-2xl",
          "animate-fade-in"
        )}
      >
        <button
          type="button"
          onClick={onClose}
          className="absolute top-2.5 end-2.5 z-10 rounded-lg p-1.5 text-muted-foreground hover:bg-muted hover:text-foreground transition-colors"
          aria-label={t("common.close")}
        >
          <X className="w-4 h-4" />
        </button>

        <div className="flex flex-col items-center px-6 pt-9 pb-1 text-center">
          <div
            className={cn(
              "flex h-[4.5rem] w-[4.5rem] shrink-0 items-center justify-center rounded-full",
              iconRing
            )}
          >
            <Icon className="h-9 w-9" strokeWidth={1.75} aria-hidden />
          </div>
          <h2
            id="confirm-dialog-title"
            className="mt-4 text-lg font-semibold leading-snug text-foreground tracking-tight"
          >
            {title}
          </h2>
          {description && (
            <p
              id="confirm-dialog-desc"
              className="mt-2 text-sm leading-relaxed text-muted-foreground max-w-[340px]"
            >
              {description}
            </p>
          )}
        </div>

        <div className="flex gap-3 border-t border-border bg-muted/40 px-5 py-4 sm:px-6">
          <Button
            type="button"
            variant="outline"
            className="flex-1 min-h-10"
            onClick={onClose}
            disabled={isLoading}
          >
            {cancelText}
          </Button>
          <Button
            type="button"
            variant={variant === "destructive" ? "destructive" : "primary"}
            className="flex-1 min-h-10 font-semibold shadow-sm"
            onClick={onConfirm}
            loading={isLoading}
            disabled={isLoading}
          >
            {confirmLabel}
          </Button>
        </div>
      </div>
    </div>
  );
}

// ─── Stat Card ────────────────────────────────────────────────────────────────
export interface StatCardProps {
  title: string;
  value: string | number;
  change?: string;
  changeType?: "up" | "down" | "neutral";
  icon: React.ReactNode;
  iconBg?: string;
}

export function StatCard({ title, value, change, changeType, icon, iconBg }: StatCardProps) {
  return (
    <Card className="p-6">
      <div className="flex items-start justify-between">
        <div>
          <p className="text-sm font-medium text-muted-foreground">{title}</p>
          <p className="text-2xl font-bold text-foreground mt-1">{value}</p>
          {change && (
            <p className={cn(
              "text-xs font-medium mt-1",
              changeType === "up" ? "text-green-600" : changeType === "down" ? "text-red-600" : "text-muted-foreground"
            )}>
              {change}
            </p>
          )}
        </div>
        <div className={cn("w-10 h-10 rounded-lg flex items-center justify-center", iconBg ?? "bg-primary/10")}>
          <span className="text-primary">{icon}</span>
        </div>
      </div>
    </Card>
  );
}

// ─── Page Header ──────────────────────────────────────────────────────────────
export interface PageHeaderProps {
  title: string;
  description?: string;
  children?: React.ReactNode;
}

export function PageHeader({ title, description, children }: PageHeaderProps) {
  return (
    <div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4 mb-6">
      <div>
        <h1 className="text-xl font-bold text-foreground">{title}</h1>
        {description && <p className="text-sm text-muted-foreground mt-0.5">{description}</p>}
      </div>
      {children && <div className="flex items-center gap-3">{children}</div>}
    </div>
  );
}

// ─── Status Badge ─────────────────────────────────────────────────────────────
export function LeadStatusBadge({ status }: { status: string }) {
  const { language } = useLanguage();
  return (
    <span
      className={cn(
        "inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium",
        LEAD_STATUS_COLORS[status] ?? "bg-gray-100 text-gray-600"
      )}
    >
      {getLabel(LEAD_STATUS_LABELS, LEAD_STATUS_LABELS_AR, status, language)}
    </span>
  );
}

const PRIORITY_LABELS = { ...TASK_PRIORITY_LABELS, CRITICAL: TICKET_PRIORITY_LABELS.CRITICAL };
const PRIORITY_LABELS_AR = { ...TASK_PRIORITY_LABELS_AR, CRITICAL: TICKET_PRIORITY_LABELS_AR.CRITICAL };

export function PriorityBadge({ priority }: { priority: string }) {
  const { language } = useLanguage();
  const classes: Record<string, string> = {
    LOW: "bg-gray-100 text-gray-600",
    MEDIUM: "bg-blue-100 text-blue-700",
    HIGH: "bg-orange-100 text-orange-700",
    URGENT: "bg-red-100 text-red-700",
    CRITICAL: "bg-red-100 text-red-700",
  };
  const label = getLabel(PRIORITY_LABELS, PRIORITY_LABELS_AR, priority, language);
  return (
    <span className={cn("inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium", classes[priority] ?? "bg-gray-100")}>
      {label}
    </span>
  );
}
