import React, { CSSProperties } from 'react';
import { useNode, UserComponent } from '@craftjs/core';
import { cssPropsToString } from '../../utils/style-helpers';

interface StarRatingProps {
  rating?: number;
  maxStars?: number;
  size?: string;
  filledColor?: string;
  emptyColor?: string;
  style?: CSSProperties;
}

export const StarRating: UserComponent<StarRatingProps> = ({
  rating = 4.5,
  maxStars = 5,
  size = '24px',
  filledColor = '#f59e0b',
  emptyColor = '#d1d5db',
  style = {},
}) => {
  const {
    connectors: { connect, drag },
    selected,
  } = useNode((node) => ({
    selected: node.events.selected,
  }));

  const stars: React.ReactNode[] = [];
  for (let i = 1; i <= maxStars; i++) {
    if (i <= Math.floor(rating)) {
      // Full star
      stars.push(
        <i
          key={i}
          className="fa fa-star"
          style={{ color: filledColor, fontSize: size }}
        />
      );
    } else if (i === Math.ceil(rating) && rating % 1 !== 0) {
      // Half star
      stars.push(
        <span key={i} style={{ position: 'relative', display: 'inline-block', fontSize: size }}>
          <i className="fa fa-star" style={{ color: emptyColor }} />
          <span style={{ position: 'absolute', left: 0, top: 0, overflow: 'hidden', width: '50%' }}>
            <i className="fa fa-star" style={{ color: filledColor }} />
          </span>
        </span>
      );
    } else {
      // Empty star
      stars.push(
        <i
          key={i}
          className="fa fa-star"
          style={{ color: emptyColor, fontSize: size }}
        />
      );
    }
  }

  return (
    <span
      ref={(ref: HTMLSpanElement | null): void => { if (ref) connect(drag(ref)); }}
      style={{
        display: 'inline-flex',
        alignItems: 'center',
        gap: '2px',
        outline: selected ? '2px solid #3b82f6' : 'none',
        ...style,
      }}
    >
      {stars}
    </span>
  );
};

/* ---------- Settings panel ---------- */

const StarRatingSettings: React.FC = () => {
  const { actions: { setProp }, props } = useNode((node) => ({
    props: node.data.props as StarRatingProps,
  }));

  const sizePresets = ['16px', '20px', '24px', '32px', '40px'];
  const filledColorPresets = ['#f59e0b', '#eab308', '#f97316', '#ef4444', '#ec4899', '#3b82f6', '#10b981', '#18181b'];

  return (
    <div style={{ padding: '12px', display: 'flex', flexDirection: 'column', gap: '14px' }}>
      <div>
        <label style={{ fontSize: 11, color: '#a1a1aa', display: 'block', marginBottom: 6 }}>
          Rating: {props.rating ?? 4.5}
        </label>
        <input
          type="range"
          min={0}
          max={props.maxStars || 5}
          step={0.5}
          value={props.rating ?? 4.5}
          onChange={(e) => setProp((p: StarRatingProps) => { p.rating = parseFloat(e.target.value); })}
          style={{ width: '100%', accentColor: '#3b82f6' }}
        />
      </div>

      <div>
        <label style={{ fontSize: 11, color: '#a1a1aa', display: 'block', marginBottom: 6 }}>Max Stars</label>
        <div style={{ display: 'flex', gap: 4 }}>
          {[3, 4, 5, 6, 7, 10].map((n) => (
            <button
              key={n}
              onClick={() => setProp((p: StarRatingProps) => {
                p.maxStars = n;
                if ((p.rating || 0) > n) p.rating = n;
              })}
              style={{
                padding: '4px 8px', fontSize: 11, borderRadius: 4, cursor: 'pointer',
                border: '1px solid #3f3f46',
                background: props.maxStars === n ? '#3b82f6' : '#27272a',
                color: '#e4e4e7',
              }}
            >
              {n}
            </button>
          ))}
        </div>
      </div>

      <div>
        <label style={{ fontSize: 11, color: '#a1a1aa', display: 'block', marginBottom: 6 }}>Star Size</label>
        <div style={{ display: 'flex', gap: 4, flexWrap: 'wrap' }}>
          {sizePresets.map((s) => (
            <button
              key={s}
              onClick={() => setProp((p: StarRatingProps) => { p.size = s; })}
              style={{
                padding: '4px 8px', fontSize: 11, borderRadius: 4, cursor: 'pointer',
                border: '1px solid #3f3f46',
                background: props.size === s ? '#3b82f6' : '#27272a',
                color: '#e4e4e7',
              }}
            >
              {s}
            </button>
          ))}
        </div>
      </div>

      <div>
        <label style={{ fontSize: 11, color: '#a1a1aa', display: 'block', marginBottom: 6 }}>Filled Color</label>
        <div style={{ display: 'flex', gap: 4, flexWrap: 'wrap' }}>
          {filledColorPresets.map((c) => (
            <button
              key={c}
              onClick={() => setProp((p: StarRatingProps) => { p.filledColor = c; })}
              style={{
                width: 24, height: 24, borderRadius: 4, border: '1px solid #3f3f46',
                backgroundColor: c, cursor: 'pointer',
                outline: props.filledColor === c ? '2px solid #3b82f6' : 'none',
                outlineOffset: 1,
              }}
            />
          ))}
        </div>
      </div>

      <div>
        <label style={{ fontSize: 11, color: '#a1a1aa', display: 'block', marginBottom: 6 }}>Empty Color</label>
        <input
          type="color"
          value={props.emptyColor || '#d1d5db'}
          onChange={(e) => setProp((p: StarRatingProps) => { p.emptyColor = e.target.value; })}
          style={{ width: 32, height: 24, border: '1px solid #3f3f46', borderRadius: 4, cursor: 'pointer', background: 'none', padding: 0 }}
        />
      </div>
    </div>
  );
};

/* ---------- Craft config ---------- */

StarRating.craft = {
  displayName: 'Star Rating',
  props: {
    rating: 4.5,
    maxStars: 5,
    size: '24px',
    filledColor: '#f59e0b',
    emptyColor: '#d1d5db',
    style: {},
  },
  rules: {
    canDrag: () => true,
    canMoveIn: () => false,
    canMoveOut: () => true,
  },
  related: {
    settings: StarRatingSettings,
  },
};

/* ---------- HTML export ---------- */

(StarRating as any).toHtml = (props: StarRatingProps, _childrenHtml: string) => {
  const rating = props.rating ?? 4.5;
  const maxStars = props.maxStars || 5;
  const size = props.size || '24px';
  const filledColor = props.filledColor || '#f59e0b';
  const emptyColor = props.emptyColor || '#d1d5db';
  const wrapperStyle = cssPropsToString({
    display: 'inline-flex',
    alignItems: 'center',
    gap: '2px',
    ...props.style,
  });

  let starsHtml = '';
  for (let i = 1; i <= maxStars; i++) {
    if (i <= Math.floor(rating)) {
      starsHtml += `<i class="fa fa-star" style="color:${filledColor};font-size:${size}"></i>`;
    } else if (i === Math.ceil(rating) && rating % 1 !== 0) {
      starsHtml += `<span style="position:relative;display:inline-block;font-size:${size}"><i class="fa fa-star" style="color:${emptyColor}"></i><span style="position:absolute;left:0;top:0;overflow:hidden;width:50%"><i class="fa fa-star" style="color:${filledColor}"></i></span></span>`;
    } else {
      starsHtml += `<i class="fa fa-star" style="color:${emptyColor};font-size:${size}"></i>`;
    }
  }

  return {
    html: `<span${wrapperStyle ? ` style="${wrapperStyle}"` : ''}>${starsHtml}</span>`,
  };
};
