import cx from 'clsx';
import { useAtom } from 'jotai';
import { toInteger } from 'lodash-es';
import { useMemo, useState } from 'react';
import { useColorFunction } from '../ColorFunctionContext';
import { ColorPicker } from '../components/ColorPicker';
import { FlexColorStand } from '../components/FlexColorStand';
import { HSegmentedControl } from '../components/HSegmentedControl';
import { LabeledPicker } from '../components/LabeledPicker';
import { ScrollArea } from '../components/ScrollArea';
import { currentPickedColor } from '../stores/colors';
import styles from './Tones.module.css';

export function Tones() {
  const { colorFn } = useColorFunction();
  const [selectedColor, setSelectedColor] = useAtom(currentPickedColor);
  const [steps, setSteps] = useState(10);
  const [tones, setTones] = useState(3);
  const [seedBias, setSeedBias] = useState(0);
  const [mode, setMode] = useState<'hex' | 'rgb' | 'hsl' | 'lab' | 'oklch'>('hex');
  const colors = useMemo(() => {
    try {
      const lightenColors = colorFn!.tonal_lighten_series(
        selectedColor,
        tones - seedBias,
        steps / 100,
      );
      const darkenColors = colorFn!.tonal_darken_series(
        selectedColor,
        tones + seedBias,
        steps / 100,
      );
      return [...darkenColors, selectedColor, ...lightenColors];
    } catch (e) {
      console.error('[Expand colors]', e);
    }
    return Array.from({ length: tones * 2 + 1 }, () => selectedColor);
  }, [selectedColor, tones, seedBias, steps]);

  return (
    <div className={cx('workspace', styles.tone_workspace)}>
      <header>
        <h3>Color Tones</h3>
        <p>By regularly changing the color tone to generate a series of light and dark colors.</p>
      </header>
      <ScrollArea enableY>
        <section className={styles.explore_section}>
          <aside className={styles.function_side}>
            <div>
              <h5>Basic color</h5>
              <ColorPicker color={selectedColor} onSelect={(color) => setSelectedColor(color)} />
            </div>
            <div>
              <h5>Series Setting</h5>
              <LabeledPicker
                title="Expand Tones"
                min={1}
                max={5}
                step={1}
                value={tones}
                onChange={(value) => {
                  setTones(toInteger(value));
                  setSeedBias(0);
                }}
              />
              <LabeledPicker
                title="Basic Bias"
                min={-(tones - 1)}
                max={tones - 1}
                value={seedBias}
                onChange={(value) => setSeedBias(toInteger(value))}
              />
              <LabeledPicker
                title="Tone Step"
                min={10}
                max={25}
                step={1}
                unit="%"
                value={steps}
                onChange={setSteps}
              />
            </div>
          </aside>
          <div className={styles.tones_content}>
            <h5>Color Tones</h5>
            <div className={styles.colors_booth}>
              {colors.map((c, index) => (
                <FlexColorStand key={`${c}-${index}`} color={c} valueMode={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' },
                ]}
                valu={mode}
                onChange={setMode}
              />
            </div>
          </div>
        </section>
      </ScrollArea>
    </div>
  );
}
