import { SchemaFieldProps, ColorField as ColorFieldType } from '@vev/utils';
import { SilkeColorPicker } from '../../silke-color-picker';
import React, { useCallback, useRef, useState } from 'react';
import { SilkeBox } from '../../silke-box';
import { SilkeIcon } from '../../silke-icon';
import { getTitle } from './utils/schema-util';
import { SilkeTextFieldOutline } from '../../silke-text-field/silke-text-field-outline';
import { SilkeTextFieldItem } from '../../silke-text-field';
import { SilkePopover } from '../../silke-popover';
import { SilkeCssNumberField } from '../../silke-css-number-field';
import tinycolor from 'tinycolor2';

const ColorField = ({
  schema,
  value,
  disabled,
  readonly,
  onChange,
}: SchemaFieldProps<ColorFieldType>) => {
  const fieldRef = useRef<HTMLDivElement>(null);
  const [open, setOpen] = useState(false);
  const hasColor = !!value && tinycolor(value).isValid();
  const tc = hasColor ? tinycolor(value) : null;
  const hex = tc ? tc.toHexString().toUpperCase() : '';
  const opacity = tc ? Math.round(tc.getAlpha() * 100) : 100;

  const handleFieldClick = useCallback(() => {
    if (!disabled) setOpen(true);
  }, [disabled]);

  const handleOpacityChange = useCallback(
    (opStr: string) => {
      const op = parseFloat(opStr);
      if (isNaN(op)) return;
      const tc = tinycolor(value || '#000');
      tc.setAlpha(Math.max(0, Math.min(100, op)) / 100);
      onChange(tc.toHex8String());
    },
    [value, onChange],
  );

  return (
    <SilkeBox flex>
      <SilkeTextFieldOutline
        ref={fieldRef}
        label={getTitle(schema)}
        tooltip={schema.description}
        size="s"
        flex
        disabled={disabled}
        onClick={handleFieldClick}
      >
        <SilkeTextFieldItem before>
          {hasColor ? (
            <SilkeBox
              size="s"
              pad="xs"
              cursor={disabled ? undefined : 'pointer'}
            >
              <div
                className="transparent-bg fill"
                style={{
                  borderRadius: 4,
                  border: '1px var(--color-neutral-30) solid',
                  overflow: 'hidden',
                }}
              >
                <div className="fill" style={{ background: value }} />
              </div>
            </SilkeBox>
          ) : (
            <SilkeBox size="s" align="center" cursor={disabled ? undefined : 'pointer'}>
              <SilkeIcon icon="theme.color" color="neutral-60" />
            </SilkeBox>
          )}
        </SilkeTextFieldItem>
        <SilkeBox
          flex
          vAlign="center"
          hPad="xs"
          overflow="hidden"
          cursor={disabled ? undefined : 'pointer'}
          tabIndex={disabled ? -1 : 0}
          data-input
          onKeyDown={(e: React.KeyboardEvent) => {
            if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); handleFieldClick(); }
          }}
        >
          <span
            style={{
              flex: 1,
              fontSize: 'var(--font-small)',
              color: hasColor ? 'var(--color-neutral-100)' : 'var(--color-neutral-60)',
              whiteSpace: 'nowrap',
              overflow: 'hidden',
              textOverflow: 'ellipsis',
            }}
          >
            {hasColor ? hex : 'Choose a color'}
          </span>
        </SilkeBox>
        {hasColor && (
          <SilkeTextFieldItem hPad="xs" onClick={(e: React.MouseEvent) => e.stopPropagation()}>
            <SilkeCssNumberField
              size="s"
              kind="ghost"
              formats={['%']}
              precision={0}
              value={`${opacity}%`}
              min={0}
              max={100}
              disabled={disabled}
              onChange={handleOpacityChange}
              style={{ width: 52 }}
            />
          </SilkeTextFieldItem>
        )}
      </SilkeTextFieldOutline>
      {open && (
        <SilkePopover
          anchor={fieldRef}
          anchorOrigin="bottom-left"
          targetOrigin="top-left"
          contextId="silke-color-picker"
          onRequestClose={() => setOpen(false)}
        >
          <SilkeBox bg="neutral-20" pad="s" gap="s" column rounded="small">
            <SilkeColorPicker value={value as any} onChange={onChange} />
          </SilkeBox>
        </SilkePopover>
      )}
    </SilkeBox>
  );
};

export default ColorField;
