import React from "react";
import type { LucideIcon } from "lucide-react";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/shared/common/ui/select";
import { cn } from "@/shared/lib/utils";

export const STYLE_SELECT_TRIGGER_CLASS =
  "h-10 w-full rounded-lg border border-gray-300 bg-white px-3 text-sm text-gray-900 shadow-sm transition-colors hover:bg-gray-50 focus:ring-2 focus:ring-purple-500 dark:border-gray-600 dark:bg-gray-900 dark:text-gray-100 dark:hover:bg-gray-800";

export const STYLE_SELECT_CONTENT_CLASS =
  "rounded-lg border border-gray-200 bg-white shadow-lg dark:border-gray-700 dark:bg-gray-900";

export const STYLE_INPUT_CLASS =
  "w-full rounded-lg border border-gray-300 bg-white px-3 py-2 text-sm text-gray-900 shadow-sm transition-colors focus:outline-none focus:ring-2 focus:ring-purple-500 dark:border-gray-600 dark:bg-gray-900 dark:text-gray-100";

export type StyleSelectOption = {
  value: string;
  label: React.ReactNode;
  disabled?: boolean;
};

type StyleSettingToggleProps = {
  isDefault: boolean;
  onToggle: () => void;
  defaultLabel?: string;
  customLabel?: string;
  className?: string;
};

export const StyleSettingToggle: React.FC<StyleSettingToggleProps> = ({
  isDefault,
  onToggle,
  defaultLabel = "Default",
  customLabel = "Custom",
  className,
}) => (
  <button
    type="button"
    onClick={onToggle}
    className={cn(
      "relative h-6 w-11 shrink-0 rounded-full transition-colors",
      isDefault ? "bg-gray-200 dark:bg-gray-600" : "bg-purple-600",
      className,
    )}
    aria-label={isDefault ? defaultLabel : customLabel}
    title={isDefault ? defaultLabel : customLabel}
  >
    <span
      className={cn(
        "absolute top-0.5 h-5 w-5 rounded-full bg-white shadow transition-transform",
        isDefault ? "left-0.5" : "left-5",
      )}
    />
  </button>
);

type StyleSettingFieldLabelProps = {
  children: React.ReactNode;
  className?: string;
  htmlFor?: string;
};

export const StyleSettingFieldLabel: React.FC<StyleSettingFieldLabelProps> = ({
  children,
  className,
  htmlFor,
}) => (
  <label
    htmlFor={htmlFor}
    className={cn(
      "mb-1.5 block text-xs font-medium text-gray-600 dark:text-gray-300",
      className,
    )}
  >
    {children}
  </label>
);

type StyleSettingSelectProps = {
  label?: React.ReactNode;
  value: string;
  onValueChange: (value: string) => void;
  options: StyleSelectOption[];
  placeholder?: string;
  disabled?: boolean;
  className?: string;
  id?: string;
};

export const StyleSettingSelect: React.FC<StyleSettingSelectProps> = ({
  label,
  value,
  onValueChange,
  options,
  placeholder,
  disabled,
  className,
  id,
}) => (
  <div className={className}>
    {label ? <StyleSettingFieldLabel htmlFor={id}>{label}</StyleSettingFieldLabel> : null}
    <Select value={value} onValueChange={onValueChange} disabled={disabled}>
      <SelectTrigger id={id} className={STYLE_SELECT_TRIGGER_CLASS}>
        <SelectValue placeholder={placeholder} />
      </SelectTrigger>
      <SelectContent className={STYLE_SELECT_CONTENT_CLASS}>
        {options.map((option) => (
          <SelectItem
            key={option.value}
            value={option.value}
            disabled={option.disabled}
            className="rounded-md text-sm focus:bg-purple-50 dark:focus:bg-purple-900/30"
          >
            {option.label}
          </SelectItem>
        ))}
      </SelectContent>
    </Select>
  </div>
);

type StyleSettingsSidebarProps = {
  title: string;
  hint?: string;
  children: React.ReactNode;
  className?: string;
  compact?: boolean;
  collapsed?: boolean;
};

export const StyleSettingsSidebar: React.FC<StyleSettingsSidebarProps> = ({
  title,
  hint,
  children,
  className,
  compact = false,
  collapsed = false,
}) => (
  <aside
    className={cn(
      "shrink-0 overflow-y-auto border-gray-200 bg-white dark:border-gray-700 dark:bg-gray-800",
      collapsed
        ? "w-16 border-b md:w-16 md:border-b-0 md:border-r"
        : compact
          ? "w-full border-b md:w-52 md:border-b-0 md:border-r"
          : "max-h-56 w-full border-b md:max-h-none md:w-56 md:border-b-0 md:border-r lg:w-64",
      className,
    )}
  >
    <div className={cn(collapsed ? "p-2" : compact ? "p-3" : "p-4")}>
      {!collapsed ? (
        <>
          <h3 className="mb-1 text-sm font-semibold text-gray-700 dark:text-gray-300">
            {title}
          </h3>
          {hint ? (
            <p className="mb-3 text-xs text-gray-500 dark:text-gray-400">{hint}</p>
          ) : null}
        </>
      ) : (
        <p className="sr-only">{title}</p>
      )}
      <nav className={cn("space-y-1", collapsed && "space-y-2")}>{children}</nav>
    </div>
  </aside>
);

export type StyleSettingsSidebarItemProps = {
  icon?: LucideIcon;
  label: React.ReactNode;
  meta?: React.ReactNode;
  badge?: React.ReactNode;
  isActive?: boolean;
  disabled?: boolean;
  onClick?: () => void;
  compact?: boolean;
  iconOnly?: boolean;
};

export const StyleSettingsSidebarItem: React.FC<StyleSettingsSidebarItemProps> = ({
  icon: Icon,
  label,
  meta,
  badge,
  isActive = false,
  disabled = false,
  onClick,
  compact = false,
  iconOnly = false,
}) => {
  const labelText = typeof label === "string" ? label : undefined;

  if (iconOnly && Icon) {
    return (
      <button
        type="button"
        disabled={disabled}
        onClick={onClick}
        title={labelText}
        aria-label={labelText}
        className={cn(
          "flex w-full items-center justify-center rounded-xl transition-all disabled:cursor-not-allowed disabled:opacity-50",
          compact ? "h-9 w-9" : "h-10 w-10",
          isActive
            ? "bg-purple-100 text-purple-700 shadow-sm ring-1 ring-purple-200 dark:bg-purple-900/40 dark:text-purple-200 dark:ring-purple-800"
            : "text-gray-500 hover:bg-gray-100 dark:text-gray-400 dark:hover:bg-gray-700/80",
        )}
      >
        <Icon className={compact ? "h-3.5 w-3.5" : "h-4 w-4"} />
      </button>
    );
  }

  return (
  <button
    type="button"
    disabled={disabled}
    onClick={onClick}
    className={cn(
      "group w-full rounded-xl text-left text-sm transition-all disabled:cursor-not-allowed disabled:opacity-50",
      compact ? "px-2.5 py-2" : "px-3 py-2.5",
      isActive
        ? "bg-purple-100 shadow-sm ring-1 ring-purple-200 dark:bg-purple-900/40 dark:ring-purple-800"
        : "text-gray-600 hover:bg-gray-100 dark:text-gray-400 dark:hover:bg-gray-700/80",
    )}
  >
    <div className="flex items-center gap-3">
      {Icon ? (
        <span
          className={cn(
            "flex shrink-0 items-center justify-center rounded-lg transition-colors",
            compact ? "h-7 w-7" : "h-8 w-8",
            isActive
              ? "bg-purple-600 text-white"
              : "bg-gray-100 text-gray-500 group-hover:bg-gray-200 dark:bg-gray-700 dark:text-gray-400",
          )}
        >
          <Icon className={compact ? "h-3.5 w-3.5" : "h-4 w-4"} />
        </span>
      ) : null}
      <div className="min-w-0 flex-1">
        <div
          className={cn(
            "truncate font-medium",
            isActive
              ? "text-purple-800 dark:text-purple-200"
              : "text-gray-700 dark:text-gray-300",
          )}
        >
          {label}
        </div>
        {meta || badge ? (
          <div className="mt-0.5 flex flex-wrap items-center gap-2 text-xs text-gray-400">
            {meta}
            {badge}
          </div>
        ) : null}
      </div>
    </div>
  </button>
  );
};

type StyleSettingCardProps = {
  title: React.ReactNode;
  subtitle?: React.ReactNode;
  code?: string;
  isDefault: boolean;
  onToggleDefault?: () => void;
  showCustomBadge?: boolean;
  children: React.ReactNode;
  className?: string;
  headerExtra?: React.ReactNode;
};

export const StyleSettingCard: React.FC<StyleSettingCardProps> = ({
  title,
  subtitle,
  code,
  isDefault,
  onToggleDefault,
  showCustomBadge = true,
  children,
  className,
  headerExtra,
}) => (
  <div
    className={cn(
      "mt-4 overflow-hidden rounded-xl border bg-white shadow-sm dark:bg-gray-800",
      isDefault
        ? "border-gray-200 dark:border-gray-700"
        : "border-purple-200 ring-1 ring-purple-100 dark:border-purple-800 dark:ring-purple-900/40",
      className,
    )}
  >
    <div className="flex items-center justify-between gap-4 border-b border-gray-100 px-4 py-3 dark:border-gray-700">
      <div className="min-w-0">
        <div className="flex flex-wrap items-center gap-2">
          <h4 className="text-sm font-semibold text-gray-900 dark:text-gray-100">
            {title}
          </h4>
          {code ? (
            <span className="rounded-md bg-gray-100 px-2 py-0.5 text-[10px] font-medium uppercase tracking-wide text-gray-500 dark:bg-gray-700 dark:text-gray-400">
              {code}
            </span>
          ) : null}
          {showCustomBadge && !isDefault ? (
            <span className="rounded-full bg-purple-100 px-2 py-0.5 text-[10px] font-semibold uppercase text-purple-700 dark:bg-purple-900/50 dark:text-purple-300">
              Customized
            </span>
          ) : null}
        </div>
        {subtitle ? (
          <p className="mt-0.5 text-xs text-gray-500 dark:text-gray-400">
            {subtitle}
          </p>
        ) : null}
      </div>
      <div className="flex items-center gap-2">
        {headerExtra}
        {onToggleDefault ? (
          <StyleSettingToggle isDefault={isDefault} onToggle={onToggleDefault} />
        ) : null}
      </div>
    </div>
    <div className={cn("p-4", isDefault && "opacity-60")}>{children}</div>
  </div>
);

export const StyleSettingPanel: React.FC<{
  title?: React.ReactNode;
  children: React.ReactNode;
  className?: string;
}> = ({ title, children, className }) => (
  <div
    className={cn(
      "rounded-xl border border-gray-200 bg-white p-4 shadow-sm dark:border-gray-700 dark:bg-gray-800/80",
      className,
    )}
  >
    {title ? (
      <h5 className="mb-3 text-xs font-semibold uppercase tracking-wide text-gray-600 dark:text-gray-300">
        {title}
      </h5>
    ) : null}
    {children}
  </div>
);
