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

interface CountdownProps {
  targetDate?: string;
  heading?: string;
  style?: CSSProperties;
  digitColor?: string;
  labelColor?: string;
  bgColor?: string;
  anchorId?: string;
}

interface TimeLeft {
  days: number;
  hours: number;
  minutes: number;
  seconds: number;
}

function getDefaultTargetDate(): string {
  const d = new Date();
  d.setDate(d.getDate() + 30);
  return d.toISOString().split('T')[0];
}

function calcTimeLeft(target: string): TimeLeft {
  const diff = new Date(target).getTime() - Date.now();
  if (diff <= 0) return { days: 0, hours: 0, minutes: 0, seconds: 0 };
  return {
    days: Math.floor(diff / (1000 * 60 * 60 * 24)),
    hours: Math.floor((diff / (1000 * 60 * 60)) % 24),
    minutes: Math.floor((diff / (1000 * 60)) % 60),
    seconds: Math.floor((diff / 1000) % 60),
  };
}

const DEFAULT_TARGET = getDefaultTargetDate();

export const Countdown: UserComponent<CountdownProps> = ({
  targetDate = DEFAULT_TARGET,
  heading = 'Coming Soon',
  style = {},
  digitColor = '#ffffff',
  labelColor = 'rgba(255,255,255,0.7)',
  bgColor = '#18181b',
  anchorId,
}) => {
  const {
    connectors: { connect, drag },
    selected,
  } = useNode((node) => ({
    selected: node.events.selected,
  }));

  const [timeLeft, setTimeLeft] = useState<TimeLeft>(() => calcTimeLeft(targetDate));

  useEffect(() => {
    setTimeLeft(calcTimeLeft(targetDate));
    const interval = setInterval(() => {
      setTimeLeft(calcTimeLeft(targetDate));
    }, 1000);
    return () => clearInterval(interval);
  }, [targetDate]);

  const pad = (n: number) => String(n).padStart(2, '0');

  const boxStyle: CSSProperties = {
    display: 'flex',
    flexDirection: 'column',
    alignItems: 'center',
    gap: '4px',
    minWidth: '80px',
  };

  const digitStyle: CSSProperties = {
    fontSize: '48px',
    fontWeight: '700',
    color: digitColor,
    lineHeight: '1',
    fontFamily: 'Inter, sans-serif',
  };

  const unitLabelStyle: CSSProperties = {
    fontSize: '12px',
    color: labelColor,
    textTransform: 'uppercase',
    letterSpacing: '0.1em',
    fontFamily: 'Inter, sans-serif',
  };

  const units: Array<{ label: string; value: number }> = [
    { label: 'Days', value: timeLeft.days },
    { label: 'Hours', value: timeLeft.hours },
    { label: 'Minutes', value: timeLeft.minutes },
    { label: 'Seconds', value: timeLeft.seconds },
  ];

  return (
    <section
      ref={(ref: HTMLElement | null): void => { if (ref) connect(drag(ref)); }}
      id={anchorId || undefined}
      style={{
        padding: '60px 20px',
        textAlign: 'center',
        backgroundColor: bgColor,
        outline: selected ? '2px solid #3b82f6' : 'none',
        ...style,
      }}
    >
      {heading && (
        <h2 style={{ fontSize: '32px', fontWeight: '700', color: digitColor, marginBottom: '32px', fontFamily: 'Inter, sans-serif' }}>
          {heading}
        </h2>
      )}
      <div style={{ display: 'flex', justifyContent: 'center', gap: '24px', flexWrap: 'wrap' }}>
        {units.map((u) => (
          <div key={u.label} style={boxStyle}>
            <span style={digitStyle}>{pad(u.value)}</span>
            <span style={unitLabelStyle}>{u.label}</span>
          </div>
        ))}
      </div>
    </section>
  );
};

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

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

  const labelStyle: CSSProperties = { fontSize: 11, color: '#a1a1aa', display: 'block', marginBottom: 6 };
  const inputStyle: CSSProperties = {
    width: '100%', padding: '4px 8px', background: '#27272a', color: '#e4e4e7',
    border: '1px solid #3f3f46', borderRadius: 4, fontSize: 12,
  };

  const colorPresets = ['#ffffff', '#f8fafc', '#3b82f6', '#10b981', '#f59e0b', '#ef4444', '#8b5cf6', '#ec4899'];
  const bgPresets = ['#18181b', '#0f172a', '#1e293b', '#1e1b4b', '#042f2e', '#27272a', '#ffffff', '#f8fafc'];

  return (
    <div style={{ padding: '12px', display: 'flex', flexDirection: 'column', gap: '14px' }}>
      <AnchorIdField />
      {/* Target date */}
      <div>
        <label style={labelStyle}>Target Date</label>
        <input
          type="date"
          value={props.targetDate || DEFAULT_TARGET}
          onChange={(e) => setProp((p: CountdownProps) => { p.targetDate = e.target.value; })}
          style={inputStyle}
        />
      </div>

      {/* Heading */}
      <div>
        <label style={labelStyle}>Heading</label>
        <input
          type="text"
          value={props.heading || ''}
          onChange={(e) => setProp((p: CountdownProps) => { p.heading = e.target.value; })}
          placeholder="Coming Soon"
          style={inputStyle}
        />
      </div>

      {/* Digit color */}
      <div>
        <label style={labelStyle}>Digit Color</label>
        <div style={{ display: 'flex', gap: 4, flexWrap: 'wrap' }}>
          {colorPresets.map((c) => (
            <button
              key={c}
              onClick={() => setProp((p: CountdownProps) => { p.digitColor = c; })}
              style={{
                width: 24, height: 24, borderRadius: 4, border: '1px solid #3f3f46',
                backgroundColor: c, cursor: 'pointer',
                outline: props.digitColor === c ? '2px solid #3b82f6' : 'none',
                outlineOffset: 1,
              }}
            />
          ))}
        </div>
      </div>

      {/* Label color */}
      <div>
        <label style={labelStyle}>Label Color</label>
        <div style={{ display: 'flex', gap: 4, flexWrap: 'wrap' }}>
          {colorPresets.map((c) => (
            <button
              key={c}
              onClick={() => setProp((p: CountdownProps) => { p.labelColor = c; })}
              style={{
                width: 24, height: 24, borderRadius: 4, border: '1px solid #3f3f46',
                backgroundColor: c, cursor: 'pointer',
                outline: props.labelColor === c ? '2px solid #3b82f6' : 'none',
                outlineOffset: 1,
              }}
            />
          ))}
        </div>
      </div>

      {/* Background color */}
      <div>
        <label style={labelStyle}>Background</label>
        <div style={{ display: 'flex', gap: 4, flexWrap: 'wrap' }}>
          {bgPresets.map((c) => (
            <button
              key={c}
              onClick={() => setProp((p: CountdownProps) => { p.bgColor = c; })}
              style={{
                width: 24, height: 24, borderRadius: 4, border: '1px solid #3f3f46',
                backgroundColor: c, cursor: 'pointer',
                outline: props.bgColor === c ? '2px solid #3b82f6' : 'none',
                outlineOffset: 1,
              }}
            />
          ))}
        </div>
      </div>
    </div>
  );
};

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

Countdown.craft = {
  displayName: 'Countdown',
  props: {
    targetDate: DEFAULT_TARGET,
    heading: 'Coming Soon',
    style: {},
    digitColor: '#ffffff',
    labelColor: 'rgba(255,255,255,0.7)',
    bgColor: '#18181b',
    anchorId: '',
  },
  rules: {
    canDrag: () => true,
    canMoveIn: () => false,
    canMoveOut: () => true,
  },
  related: {
    settings: CountdownSettings,
  },
};

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

(Countdown as any).toHtml = (props: CountdownProps, _childrenHtml: string) => {
  const esc = (s: any) => String(s ?? "").replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
  const {
    targetDate = DEFAULT_TARGET,
    heading = 'Coming Soon',
    style = {},
    digitColor = '#ffffff',
    labelColor = 'rgba(255,255,255,0.7)',
    bgColor = '#18181b',
  } = props;

  const sectionStyle = cssPropsToString({
    padding: '60px 20px',
    textAlign: 'center',
    backgroundColor: bgColor,
    ...style,
  });
  const idAttr = props.anchorId ? ` id="${esc(props.anchorId)}"` : '';

  const headingHtml = heading
    ? `<h2 style="font-size:32px;font-weight:700;color:${digitColor};margin-bottom:32px;font-family:Inter,sans-serif">${esc(heading)}</h2>`
    : '';

  const boxStyle = 'display:flex;flex-direction:column;align-items:center;gap:4px;min-width:80px';
  const dStyle = `font-size:48px;font-weight:700;color:${digitColor};line-height:1;font-family:Inter,sans-serif`;
  const lStyle = `font-size:12px;color:${labelColor};text-transform:uppercase;letter-spacing:0.1em;font-family:Inter,sans-serif`;

  // Generate a unique ID for this countdown instance
  const uid = 'cd_' + Math.random().toString(36).slice(2, 8);

  return {
    html: `<section${idAttr}${sectionStyle ? ` style="${sectionStyle}"` : ''}>
  ${headingHtml}
  <div style="display:flex;justify-content:center;gap:24px;flex-wrap:wrap">
    <div style="${boxStyle}"><span id="${uid}_d" style="${dStyle}">00</span><span style="${lStyle}">Days</span></div>
    <div style="${boxStyle}"><span id="${uid}_h" style="${dStyle}">00</span><span style="${lStyle}">Hours</span></div>
    <div style="${boxStyle}"><span id="${uid}_m" style="${dStyle}">00</span><span style="${lStyle}">Minutes</span></div>
    <div style="${boxStyle}"><span id="${uid}_s" style="${dStyle}">00</span><span style="${lStyle}">Seconds</span></div>
  </div>
  <script>
  (function(){
    var target = new Date("${targetDate}").getTime();
    function pad(n){ return String(n).padStart(2,'0'); }
    function update(){
      var diff = target - Date.now();
      if(diff<=0){ diff=0; }
      var d = Math.floor(diff/(1000*60*60*24));
      var h = Math.floor((diff/(1000*60*60))%24);
      var m = Math.floor((diff/(1000*60))%60);
      var s = Math.floor((diff/1000)%60);
      document.getElementById("${uid}_d").textContent = pad(d);
      document.getElementById("${uid}_h").textContent = pad(h);
      document.getElementById("${uid}_m").textContent = pad(m);
      document.getElementById("${uid}_s").textContent = pad(s);
    }
    update();
    setInterval(update,1000);
  })();
  </script>
</section>`,
  };
};
