import { useMemo } from 'react';
import type { ReactNode } from 'react';
import type { OverlayLayer } from './ChartPanel.types';
import { IconEye, IconLock, IconTrash } from './ChartIcons';

type Props = {
  open: boolean;
  layers: OverlayLayer[];
  onRequestClose: () => void;

  onToggleLayerVisible: (layerId: string) => void;
  onToggleLayerLocked: (layerId: string) => void;
  onSetLayerOpacity: (layerId: string, opacity: number) => void;

  fibPresent: boolean;
  fibSelected: boolean;
  fibVisible: boolean;
  fibLocked: boolean;
  fibOpacity: number;
  onSelectFib: () => void;
  onToggleFibVisible: () => void;
  onToggleFibLocked: () => void;
  onSetFibOpacity: (opacity: number) => void;
  onDeleteFib: () => void;
};

function clamp01(v: number): number {
  if (!Number.isFinite(v)) return 1;
  return Math.max(0, Math.min(1, v));
}

function opacityToPct(opacity: number): number {
  return Math.round(clamp01(opacity) * 100);
}

function pctToOpacity(pct: number): number {
  if (!Number.isFinite(pct)) return 1;
  return clamp01(pct / 100);
}

function IconButton({
  title,
  active,
  disabled,
  onClick,
  children,
}: {
  title: string;
  active?: boolean;
  disabled?: boolean;
  onClick: () => void;
  children: ReactNode;
}) {
  return (
    <button
      type="button"
      className={['layersBtn', active ? 'layersBtn--active' : null].filter(Boolean).join(' ')}
      title={title}
      aria-label={title}
      onClick={(e) => {
        e.preventDefault();
        e.stopPropagation();
        onClick();
      }}
      disabled={disabled}
    >
      {children}
    </button>
  );
}

function OpacitySlider({
  value,
  disabled,
  onChange,
}: {
  value: number;
  disabled?: boolean;
  onChange: (next: number) => void;
}) {
  const pct = opacityToPct(value);
  return (
    <div className="layersOpacity">
      <input
        className="layersOpacity__range"
        type="range"
        min={0}
        max={100}
        value={pct}
        onChange={(e) => onChange(pctToOpacity(Number(e.target.value)))}
        disabled={disabled}
      />
      <div className="layersOpacity__pct">{pct}%</div>
    </div>
  );
}

export default function ChartLayersPanel({
  open,
  layers,
  onRequestClose,
  onToggleLayerVisible,
  onToggleLayerLocked,
  onSetLayerOpacity,
  fibPresent,
  fibSelected,
  fibVisible,
  fibLocked,
  fibOpacity,
  onSelectFib,
  onToggleFibVisible,
  onToggleFibLocked,
  onSetFibOpacity,
  onDeleteFib,
}: Props) {
  const drawingsLayer = useMemo(() => layers.find((l) => l.id === 'drawings'), [layers]);

  return (
    <>
      <div
        className={['chartLayersBackdrop', open ? 'chartLayersBackdrop--open' : null].filter(Boolean).join(' ')}
        onClick={open ? onRequestClose : undefined}
      />
      <div className={['chartLayersPanel', open ? 'chartLayersPanel--open' : null].filter(Boolean).join(' ')}>
        <div className="chartLayersPanel__head">
          <div className="chartLayersPanel__title">Layers</div>
          <button type="button" className="chartLayersPanel__close" onClick={onRequestClose} aria-label="Close">
            ✕
          </button>
        </div>

        <div className="chartLayersTable">
          <div className="chartLayersRow chartLayersRow--head">
            <div className="chartLayersCell chartLayersCell--icon" title="Visible">
              <IconEye />
            </div>
            <div className="chartLayersCell chartLayersCell--icon" title="Lock">
              <IconLock />
            </div>
            <div className="chartLayersCell chartLayersCell--name">Name</div>
            <div className="chartLayersCell chartLayersCell--opacity">Opacity</div>
            <div className="chartLayersCell chartLayersCell--actions">Actions</div>
          </div>

          {layers.map((layer) => (
            <div key={layer.id} className="chartLayersRow chartLayersRow--layer">
              <div className="chartLayersCell chartLayersCell--icon">
                <IconButton title="Toggle visible" active={layer.visible} onClick={() => onToggleLayerVisible(layer.id)}>
                  <IconEye />
                </IconButton>
              </div>
              <div className="chartLayersCell chartLayersCell--icon">
                <IconButton title="Toggle lock" active={layer.locked} onClick={() => onToggleLayerLocked(layer.id)}>
                  <IconLock />
                </IconButton>
              </div>
              <div className="chartLayersCell chartLayersCell--name">
                <div className="layersName layersName--layer">
                  {layer.name}
                  {layer.id === 'drawings' ? <span className="layersName__meta">{fibPresent ? ' (1)' : ' (0)'}</span> : null}
                </div>
              </div>
              <div className="chartLayersCell chartLayersCell--opacity">
                <OpacitySlider value={layer.opacity} onChange={(next) => onSetLayerOpacity(layer.id, next)} />
              </div>
              <div className="chartLayersCell chartLayersCell--actions" />
            </div>
          ))}

          {drawingsLayer && fibPresent ? (
            <div
              className={['chartLayersRow', 'chartLayersRow--object', fibSelected ? 'chartLayersRow--selected' : null]
                .filter(Boolean)
                .join(' ')}
              onClick={onSelectFib}
              role="button"
              tabIndex={0}
            >
              <div className="chartLayersCell chartLayersCell--icon">
                <IconButton title="Toggle visible" active={fibVisible} onClick={onToggleFibVisible}>
                  <IconEye />
                </IconButton>
              </div>
              <div className="chartLayersCell chartLayersCell--icon">
                <IconButton title="Toggle lock" active={fibLocked} onClick={onToggleFibLocked}>
                  <IconLock />
                </IconButton>
              </div>
              <div className="chartLayersCell chartLayersCell--name">
                <div className="layersName layersName--object">Fib Retracement</div>
              </div>
              <div className="chartLayersCell chartLayersCell--opacity">
                <OpacitySlider value={fibOpacity} onChange={onSetFibOpacity} />
              </div>
              <div className="chartLayersCell chartLayersCell--actions">
                <IconButton title="Delete fib" onClick={onDeleteFib}>
                  <IconTrash />
                </IconButton>
              </div>
            </div>
          ) : null}
        </div>
      </div>
    </>
  );
}
