import cx from 'clsx';
import { useAtom } from 'jotai';
import { useEffect, useMemo, useState } from 'react';
import { ColorPicker } from '../components/ColorPicker';
import { HSegmentedControl } from '../components/HSegmentedControl';
import { Labeled } from '../components/Labeled';
import { LabeledPicker } from '../components/LabeledPicker';
import { ScrollArea } from '../components/ScrollArea';
import { Switch } from '../components/Switch';
import { PaletteColors } from '../page-components/auto-palette/PaletteColors';
import { currentPickedColor } from '../stores/colors';
import styles from './Palette.module.css';

type ColorModes = 'hex' | 'rgb' | 'hsl' | 'lab' | 'oklch';

export function AutomaticPalette() {
  const [selectedColor, setSelectedColor] = useAtom(currentPickedColor);
  const [useReferenceColor, setUseReferenceColor] = useState(false);
  const [swatchAmount, setSwatchAmount] = useState(5);
  const maxBias = useMemo(
    () => (swatchAmount > 3 ? Math.floor(swatchAmount / 2) - 1 : 0),
    [swatchAmount],
  );
  const [referenceBias, setReferenceBias] = useState(0);
  const [minLightness, setMinLightness] = useState(10);
  const [maxLightness, setMaxLightness] = useState(90);
  const [mode, setMode] = useState<ColorModes>('hex');

  useEffect(() => {
    if (useReferenceColor) {
      setReferenceBias(0);
    }
  }, [swatchAmount, useReferenceColor]);

  return (
    <div className={cx('workspace', styles.palette_workspace)}>
      <header>
        <h3>Automatic Palette</h3>
        <p>
          Automatically generate a color palette suitable for UI color matching according to the
          given color algorithm.
        </p>
      </header>
      <ScrollArea enableY>
        <section className={styles.palette_section}>
          <aside className={styles.function_side}>
            <div>
              <h5>Reference Color</h5>
              <ColorPicker color={selectedColor} onSelect={(color) => setSelectedColor(color)} />
            </div>
            <div>
              <h5>Palette Setting</h5>
              <Labeled label="Use Reference Color" inline>
                <Switch checked={useReferenceColor} onChange={setUseReferenceColor} />
              </Labeled>
              <LabeledPicker
                title="Swatch Amount"
                min={3}
                max={12}
                step={1}
                value={swatchAmount}
                onChange={(value) => setSwatchAmount(value)}
              />
              <LabeledPicker
                title="Reference Bias"
                min={-maxBias}
                max={maxBias}
                step={1}
                value={referenceBias}
                onChange={setReferenceBias}
                disabled={!useReferenceColor || maxBias < 2}
              />
              <LabeledPicker
                title="Min Lightness"
                min={0}
                max={100}
                step={1}
                value={minLightness}
                onChange={setMinLightness}
                unit="%"
              />
              <LabeledPicker
                title="Max Lightness"
                min={0}
                max={100}
                step={1}
                value={maxLightness}
                onChange={setMaxLightness}
                unit="%"
              />
            </div>
          </aside>
          <div className={styles.palette_content}>
            <h5>Generated Palette</h5>
            <div className={styles.colors_booth}>
              <PaletteColors
                color={selectedColor}
                swatchAmount={swatchAmount}
                min={minLightness / 100}
                max={maxLightness / 100}
                useReference={useReferenceColor}
                referenceBias={referenceBias}
                copyMode={mode}
              />
            </div>
            <div className={styles.color_value_mode}>
              <label>Copy color value in</label>
              <HSegmentedControl
                options={[
                  { label: 'HEX', value: 'hex' },
                  { label: 'RGB', value: 'rgb' },
                  { label: 'HSL', value: 'hsl' },
                  { label: 'LAB', value: 'lab' },
                  { label: 'OKLCH', value: 'oklch' },
                ]}
                value={mode}
                onChange={(v) => setMode(v as ColorModes)}
              />
            </div>
          </div>
        </section>
      </ScrollArea>
    </div>
  );
}
