import { useState, useRef, useEffect } from 'react';
import type { Layer } from '@common/services/layerService';

const PRESET_COLORS = [
  '#ef4444',
  '#f97316',
  '#eab308',
  '#22c55e',
  '#06b6d4',
  '#3b82f6',
  '#8b5cf6',
  '#a855f7',
  '#ec4899',
  '#f43f5e',
  '#64748b',
  '#ffffff',
];

interface LayerTreeProps {
  layers: (Layer & { children?: Layer[] })[];
  enabledLayers: Set<string>;
  onToggleLayer: (layerId: string, enabled: boolean) => void;
  layerColors?: Record<string, string>;
  onColorChange?: (layerId: string, color: string) => void;
}

export function LayerTree({
  layers,
  enabledLayers,
  onToggleLayer,
  layerColors = {},
  onColorChange,
}: LayerTreeProps) {
  const allLeafIds = getAllLeafIds(layers);
  const allEnabled = allLeafIds.length > 0 && allLeafIds.every((id) => enabledLayers.has(id));

  const handleToggleAll = () => {
    const newState = !allEnabled;
    getAllNodeIds(layers).forEach((id) => onToggleLayer(id, newState));
  };

  return (
    <div className="px-1">
      <div className="flex items-center justify-between px-2 pt-1 pb-2 mb-1 border-b border-stroke">
        <span className="text-caption font-semibold text-fg-disabled">전체 레이어</span>
        <div
          className={`lyr-sw ${allEnabled ? 'on' : ''} cursor-pointer`}
          onClick={handleToggleAll}
        />
      </div>

      {layers.map((layer) => (
        <LayerNode
          key={layer.id}
          layer={layer}
          enabledLayers={enabledLayers}
          onToggleLayer={onToggleLayer}
          layerColors={layerColors}
          onColorChange={onColorChange}
          depth={0}
        />
      ))}
    </div>
  );
}

function getAllLeafIds(layers: (Layer & { children?: Layer[] })[]): string[] {
  const ids: string[] = [];
  for (const l of layers) {
    if (l.children && l.children.length > 0) {
      ids.push(...getAllLeafIds(l.children));
    } else {
      ids.push(l.id);
    }
  }
  return ids;
}

function getAllNodeIds(layers: (Layer & { children?: Layer[] })[]): string[] {
  const ids: string[] = [];
  for (const l of layers) {
    ids.push(l.id);
    if (l.children && l.children.length > 0) {
      ids.push(...getAllNodeIds(l.children));
    }
  }
  return ids;
}

interface LayerNodeProps {
  layer: Layer & { children?: Layer[] };
  enabledLayers: Set<string>;
  onToggleLayer: (layerId: string, enabled: boolean) => void;
  layerColors: Record<string, string>;
  onColorChange?: (layerId: string, color: string) => void;
  depth: number;
}

function LayerNode({
  layer,
  enabledLayers,
  onToggleLayer,
  layerColors,
  onColorChange,
  depth,
}: LayerNodeProps) {
  const [expanded, setExpanded] = useState(depth < 1);
  const hasChildren = layer.children && layer.children.length > 0;
  const isEnabled = enabledLayers.has(layer.id);

  const getAllDescendantIds = (node: Layer & { children?: Layer[] }): string[] => {
    const ids: string[] = [];
    if (node.children) {
      for (const child of node.children) {
        ids.push(child.id);
        ids.push(...getAllDescendantIds(child));
      }
    }
    return ids;
  };

  const handleSwitchClick = (e: React.MouseEvent) => {
    e.stopPropagation();
    const newState = !isEnabled;
    onToggleLayer(layer.id, newState);
    if (hasChildren) {
      getAllDescendantIds(layer).forEach((id) => onToggleLayer(id, newState));
    }
  };

  const handleHeaderClick = () => {
    if (hasChildren) setExpanded(!expanded);
  };

  // depth 0 — 대분류 (lyr-g1 / lyr-h1)
  if (depth === 0) {
    return (
      <div className="lyr-g1">
        <div className="lyr-h1" onClick={handleHeaderClick}>
          {hasChildren ? (
            <span className={`lyr-arr ${expanded ? 'open' : ''}`}>▶</span>
          ) : (
            <span className="lyr-arr invisible">▶</span>
          )}
          <div className={`lyr-sw ${isEnabled ? 'on' : ''}`} onClick={handleSwitchClick} />
          {layer.icon && <span>{layer.icon}</span>}
          {layer.name}
          {layer.count !== undefined && (
            <span className="lyr-h1-cnt">{layer.count.toLocaleString()}</span>
          )}
        </div>
        {hasChildren && (
          <div
            className={`lyr-c1 ${expanded ? '' : 'collapsed'}`}
            style={{ maxHeight: expanded ? '800px' : '0' }}
          >
            {layer.children!.map((child) => (
              <LayerNode
                key={child.id}
                layer={child}
                enabledLayers={enabledLayers}
                onToggleLayer={onToggleLayer}
                layerColors={layerColors}
                onColorChange={onColorChange}
                depth={depth + 1}
              />
            ))}
          </div>
        )}
      </div>
    );
  }

  // depth 1 — 중분류 (lyr-g2 / lyr-h2) 또는 leaf
  if (depth === 1) {
    // 자식 없는 depth 1 → leaf로 렌더링 (해양관측·기상 하위 등)
    if (!hasChildren) {
      return (
        <div
          className="lyr-t"
          onClick={(e) => {
            if (!(e.target as HTMLElement).closest('.lyr-csw, .lyr-cpop')) handleSwitchClick(e);
          }}
        >
          <div className={`lyr-sw ${isEnabled ? 'on' : ''}`} />
          {layer.icon && <span>{layer.icon}</span>}
          <span className="flex-1">{layer.name}</span>
          {layer.count !== undefined && (
            <span className="lyr-cnt">{layer.count.toLocaleString()}</span>
          )}
          {onColorChange && (
            <ColorSwatch
              color={layerColors[layer.id]}
              onChange={(c) => onColorChange(layer.id, c)}
            />
          )}
        </div>
      );
    }

    return (
      <div className="lyr-g2">
        <div className="lyr-h2" onClick={handleHeaderClick}>
          {hasChildren ? (
            <span className={`lyr-arr ${expanded ? 'open' : ''}`}>▶</span>
          ) : (
            <span className="lyr-arr invisible">▶</span>
          )}
          <div className={`lyr-sw ${isEnabled ? 'on' : ''}`} onClick={handleSwitchClick} />
          {layer.icon && <span>{layer.icon}</span>}
          {layer.name}
          {layer.count !== undefined && (
            <span className="lyr-h2-cnt">{layer.count.toLocaleString()}</span>
          )}
        </div>
        <div
          className={`lyr-c2 ${expanded ? '' : 'collapsed'}`}
          style={{ maxHeight: expanded ? '600px' : '0' }}
        >
          {layer.children!.map((child) => (
            <LayerNode
              key={child.id}
              layer={child}
              enabledLayers={enabledLayers}
              onToggleLayer={onToggleLayer}
              layerColors={layerColors}
              onColorChange={onColorChange}
              depth={depth + 1}
            />
          ))}
        </div>
      </div>
    );
  }

  // depth 2+ leaf — 색상 스와치 포함
  if (!hasChildren) {
    return (
      <div
        className="lyr-t"
        onClick={(e) => {
          if (!(e.target as HTMLElement).closest('.lyr-csw, .lyr-cpop')) handleSwitchClick(e);
        }}
      >
        <div className={`lyr-sw ${isEnabled ? 'on' : ''}`} />
        {layer.icon && <span>{layer.icon}</span>}
        <span className="flex-1">{layer.name}</span>
        {layer.count !== undefined && (
          <span className="lyr-cnt">{layer.count.toLocaleString()}</span>
        )}
        {onColorChange && (
          <ColorSwatch color={layerColors[layer.id]} onChange={(c) => onColorChange(layer.id, c)} />
        )}
      </div>
    );
  }

  // depth 2+ with children
  return (
    <div>
      <div className="lyr-t gap-1.5">
        <span
          className={`lyr-arr ${expanded ? 'open' : ''} cursor-pointer text-caption w-[10px] text-center`}
          onClick={handleHeaderClick}
        >
          ▶
        </span>
        <div className={`lyr-sw ${isEnabled ? 'on' : ''}`} onClick={handleSwitchClick} />
        {layer.icon && <span>{layer.icon}</span>}
        <span onClick={handleHeaderClick} className="cursor-pointer flex-1">
          {layer.name}
        </span>
        {layer.count !== undefined && (
          <span className="lyr-cnt">{layer.count.toLocaleString()}</span>
        )}
      </div>
      {expanded && (
        <div className="pl-4">
          {layer.children!.map((child) => (
            <LayerNode
              key={child.id}
              layer={child}
              enabledLayers={enabledLayers}
              onToggleLayer={onToggleLayer}
              layerColors={layerColors}
              onColorChange={onColorChange}
              depth={depth + 1}
            />
          ))}
        </div>
      )}
    </div>
  );
}

// 색상 스와치 + 피커
function ColorSwatch({ color, onChange }: { color?: string; onChange: (c: string) => void }) {
  const [open, setOpen] = useState(false);
  const ref = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (!open) return;
    const handler = (e: MouseEvent) => {
      if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false);
    };
    document.addEventListener('mousedown', handler);
    return () => document.removeEventListener('mousedown', handler);
  }, [open]);

  return (
    <div ref={ref} className="relative shrink-0">
      <div
        className={`lyr-csw ${color ? 'has-color' : ''}`}
        style={color ? { borderColor: color, background: color } : {}}
        onClick={(e) => {
          e.stopPropagation();
          setOpen(!open);
        }}
      />
      {open && (
        <div className="lyr-cpop show" onClick={(e) => e.stopPropagation()}>
          <div className="lyr-cpr">
            {PRESET_COLORS.map((pc) => (
              <div
                key={pc}
                className={`lyr-cpr-i ${color === pc ? 'sel' : ''}`}
                style={{ background: pc }}
                onClick={() => {
                  onChange(pc);
                  setOpen(false);
                }}
              />
            ))}
          </div>
          <div className="lyr-ccustom">
            <label>커스텀</label>
            <input
              type="color"
              value={color || '#06b6d4'}
              onChange={(e) => {
                onChange(e.target.value);
                setOpen(false);
              }}
            />
          </div>
        </div>
      )}
    </div>
  );
}
