import { useState, useEffect, useRef, useCallback, type FormEvent } from 'react';
import { Modal } from '../../components/Modal';
import api from '../../api/client';
import type { ExpertProject } from '../ExpertProfileTab';
import styles from '../ExpertProfileTab.module.css';

interface ProjectModalProps {
  isOpen: boolean;
  onClose: () => void;
  onSave: () => Promise<void>;
  project: ExpertProject | null;
}

const MONTHS = [
  { value: 1, label: 'Januar' }, { value: 2, label: 'Februar' },
  { value: 3, label: 'März' }, { value: 4, label: 'April' },
  { value: 5, label: 'Mai' }, { value: 6, label: 'Juni' },
  { value: 7, label: 'Juli' }, { value: 8, label: 'August' },
  { value: 9, label: 'September' }, { value: 10, label: 'Oktober' },
  { value: 11, label: 'November' }, { value: 12, label: 'Dezember' },
];

const COMPANY_SIZES = ['1-10', '11-50', '51-200', '201-500', '501-1000', '1001-5000', '5000+'];

const INDUSTRIES = [
  'IT-Dienstleistung', 'Software-Entwicklung', 'Cloud & Hosting', 'Telekommunikation',
  'Finanzdienstleistung', 'Versicherung', 'Gesundheitswesen', 'Pharma & Medizintechnik',
  'Automobilindustrie', 'Maschinenbau', 'Energiewirtschaft', 'Logistik & Transport',
  'Handel & E-Commerce', 'Medien & Unterhaltung', 'Bildung & Forschung',
  'Öffentlicher Sektor', 'Beratung & Consulting', 'Luft- und Raumfahrt',
  'Chemie & Werkstoffe', 'Sonstige',
];

const currentYear = new Date().getFullYear();
const YEARS = Array.from({ length: 40 }, (_, i) => currentYear - i);

// ─── BulletEditor helpers (module-level, pure) ───────────────────────────────

/**
 * Wrap or unwrap the current selection with an inline formatting marker.
 * - With selection: wraps/unwraps (toggle)
 * - Without selection: inserts marker pair with cursor inside
 */
function blWrapFormat(
  ta: HTMLTextAreaElement,
  v: string,
  marker: string,
  onChange: (val: string) => void,
): void {
  const start = ta.selectionStart;
  const end = ta.selectionEnd;
  const mLen = marker.length;
  const selected = v.substring(start, end);

  if (selected.startsWith(marker) && selected.endsWith(marker) && selected.length > mLen * 2) {
    // Already wrapped → unwrap
    const inner = selected.substring(mLen, selected.length - mLen);
    onChange(v.substring(0, start) + inner + v.substring(end));
    requestAnimationFrame(() => {
      ta.selectionStart = start;
      ta.selectionEnd = start + inner.length;
      ta.focus();
    });
  } else if (selected.length > 0) {
    // Wrap selection
    onChange(v.substring(0, start) + marker + selected + marker + v.substring(end));
    requestAnimationFrame(() => {
      ta.selectionStart = start + mLen;
      ta.selectionEnd = end + mLen;
      ta.focus();
    });
  } else {
    // No selection: insert empty marker pair, cursor inside
    onChange(v.substring(0, start) + marker + marker + v.substring(start));
    requestAnimationFrame(() => {
      ta.selectionStart = ta.selectionEnd = start + mLen;
      ta.focus();
    });
  }
}

/** Parse the line at cursor position into its structural components */
function blLineAt(val: string, pos: number) {
  const s = val.lastIndexOf('\n', pos - 1) + 1;
  const eIdx = val.indexOf('\n', pos);
  const e = eIdx === -1 ? val.length : eIdx;
  const text = val.substring(s, e);
  const bm = text.match(/^( *)(• )([\s\S]*)$/);
  const nm = text.match(/^( *)(\d+)\. ([\s\S]*)$/);
  return {
    s,
    e,
    text,
    indent: bm?.[1] ?? nm?.[1] ?? (text.match(/^ */)?.[0] ?? ''),
    isBullet: !!bm,
    isNum: !!nm,
    num: nm ? parseInt(nm[2]) : 0,
    body: bm ? bm[3] : nm ? nm[3] : text.replace(/^ */, ''),
  };
}

// ─── BulletEditor component ───────────────────────────────────────────────────

/**
 * Lightweight rich-text-like editor for task lists.
 * Supports bullet lists (• ), numbered lists (1. 2. 3.),
 * Tab/Shift+Tab indentation, and auto-continuation on Enter.
 * No external dependencies — plain textarea with smart keyboard handling.
 */
function BulletEditor({
  value,
  onChange,
  placeholder,
  maxLength,
  rows = 6,
}: {
  value: string;
  onChange: (val: string) => void;
  placeholder?: string;
  maxLength?: number;
  rows?: number;
}) {
  const textareaRef = useRef<HTMLTextAreaElement>(null);

  /** Replace the current line and reposition cursor */
  function applyLineMutation(
    ta: HTMLTextAreaElement,
    v: string,
    s: number,
    e: number,
    newLine: string,
    newPos: number,
  ) {
    onChange(v.substring(0, s) + newLine + v.substring(e));
    requestAnimationFrame(() => {
      ta.selectionStart = ta.selectionEnd = newPos;
      ta.focus();
    });
  }

  // ── Toggle bullet list ──────────────────────────────────────────────────────
  const toggleBullet = useCallback(() => {
    const ta = textareaRef.current;
    if (!ta) return;
    const pos = ta.selectionStart;
    const v = ta.value;
    const { s, e, indent, isBullet, isNum, num, body } = blLineAt(v, pos);

    if (isBullet) {
      // Remove bullet
      applyLineMutation(ta, v, s, e, indent + body, Math.max(s + indent.length, pos - 2));
    } else if (isNum) {
      // Convert numbered → bullet
      const oldNumLen = String(num).length + 2; // "N. "
      applyLineMutation(ta, v, s, e, indent + '• ' + body, Math.max(s + indent.length + 2, pos - oldNumLen + 2));
    } else {
      // Add bullet
      applyLineMutation(ta, v, s, e, indent + '• ' + body, pos + 2);
    }
  }, [onChange]); // eslint-disable-line react-hooks/exhaustive-deps

  // ── Inline formatting: Bold / Italic / Underline ───────────────────────────
  const wrapBold = useCallback(() => {
    const ta = textareaRef.current;
    if (ta) blWrapFormat(ta, ta.value, '**', onChange);
  }, [onChange]);

  const wrapItalic = useCallback(() => {
    const ta = textareaRef.current;
    if (ta) blWrapFormat(ta, ta.value, '*', onChange);
  }, [onChange]);

  const wrapUnderline = useCallback(() => {
    const ta = textareaRef.current;
    if (ta) blWrapFormat(ta, ta.value, '__', onChange);
  }, [onChange]);

  // ── Toggle numbered list ────────────────────────────────────────────────────
  const toggleNumbered = useCallback(() => {
    const ta = textareaRef.current;
    if (!ta) return;
    const pos = ta.selectionStart;
    const v = ta.value;
    const { s, e, indent, isBullet, isNum, num, body } = blLineAt(v, pos);

    if (isNum) {
      // Remove numbered
      const oldNumLen = String(num).length + 2;
      applyLineMutation(ta, v, s, e, indent + body, Math.max(s + indent.length, pos - oldNumLen));
    } else if (isBullet) {
      // Convert bullet → numbered
      applyLineMutation(ta, v, s, e, indent + '1. ' + body, s + indent.length + 3);
    } else {
      // Add numbered
      applyLineMutation(ta, v, s, e, indent + '1. ' + body, pos + 3);
    }
  }, [onChange]); // eslint-disable-line react-hooks/exhaustive-deps

  // ── Keyboard handler: Tab/Shift+Tab + Enter ─────────────────────────────────
  const handleKeyDown = useCallback(
    (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
      const ta = textareaRef.current;
      if (!ta) return;
      const pos = ta.selectionStart;
      const v = ta.value;
      const info = blLineAt(v, pos);

      // Ctrl+B / Ctrl+I / Ctrl+U → inline formatting
      if ((e.ctrlKey || e.metaKey) && ['b', 'i', 'u'].includes(e.key)) {
        e.preventDefault();
        if (e.key === 'b') blWrapFormat(ta, v, '**', onChange);
        else if (e.key === 'i') blWrapFormat(ta, v, '*', onChange);
        else if (e.key === 'u') blWrapFormat(ta, v, '__', onChange);
        return;
      }

      // Tab → indent (+2 spaces at line start)
      // Shift+Tab → outdent (-2 spaces from line start)
      if (e.key === 'Tab') {
        e.preventDefault();
        if (e.shiftKey) {
          if (info.text.startsWith('  ')) {
            onChange(v.substring(0, info.s) + info.text.substring(2) + v.substring(info.e));
            requestAnimationFrame(() => {
              ta.selectionStart = ta.selectionEnd = Math.max(info.s, pos - 2);
            });
          }
        } else {
          onChange(v.substring(0, info.s) + '  ' + v.substring(info.s));
          requestAnimationFrame(() => {
            ta.selectionStart = ta.selectionEnd = pos + 2;
          });
        }
        return;
      }

      if (e.key !== 'Enter') return;

      const isEmptyItem = (info.isBullet || info.isNum) && info.body.trim() === '';

      if (isEmptyItem) {
        // Empty list item → exit list, keep indentation only
        e.preventDefault();
        onChange(v.substring(0, info.s) + info.indent + v.substring(info.e));
        requestAnimationFrame(() => {
          ta.selectionStart = ta.selectionEnd = info.s + info.indent.length;
        });
      } else if (info.isBullet) {
        // Continue bullet on next line (preserving indentation)
        e.preventDefault();
        const ins = '\n' + info.indent + '• ';
        onChange(v.substring(0, pos) + ins + v.substring(ta.selectionEnd));
        requestAnimationFrame(() => {
          ta.selectionStart = ta.selectionEnd = pos + ins.length;
        });
      } else if (info.isNum) {
        // Continue numbered list with incremented number
        e.preventDefault();
        const ins = '\n' + info.indent + String(info.num + 1) + '. ';
        onChange(v.substring(0, pos) + ins + v.substring(ta.selectionEnd));
        requestAnimationFrame(() => {
          ta.selectionStart = ta.selectionEnd = pos + ins.length;
        });
      }
    },
    [onChange],
  );

  return (
    <div className={styles.bulletEditor}>
      <div className={styles.bulletToolbar}>
        <button
          type="button"
          className={styles.bulletBtn}
          onClick={toggleBullet}
          title="Aufzählungsliste ein/aus (• Punkt)"
        >
          ☰ Liste
        </button>
        <button
          type="button"
          className={styles.bulletBtn}
          onClick={toggleNumbered}
          title="Nummerierte Liste ein/aus (1. 2. 3.)"
        >
          1. Liste
        </button>
        <span className={styles.bulletToolbarSep} />
        <button
          type="button"
          className={`${styles.bulletBtn} ${styles.bulletBtnBold}`}
          onClick={wrapBold}
          title="Fett (Strg+B) — Text markieren, dann B drücken"
        >
          B
        </button>
        <button
          type="button"
          className={`${styles.bulletBtn} ${styles.bulletBtnItalic}`}
          onClick={wrapItalic}
          title="Kursiv (Strg+I) — Text markieren, dann I drücken"
        >
          I
        </button>
        <button
          type="button"
          className={`${styles.bulletBtn} ${styles.bulletBtnUnderline}`}
          onClick={wrapUnderline}
          title="Unterstrichen (Strg+U) — Text markieren, dann U drücken"
        >
          U
        </button>
        <span className={styles.bulletToolbarSep} />
        <span className={styles.bulletToolbarHint}>Tab = einrücken · ⇧Tab = ausrücken</span>
      </div>
      <textarea
        ref={textareaRef}
        className={styles.bulletEditorTextarea}
        value={value}
        onChange={(ev) => onChange(ev.target.value)}
        onKeyDown={handleKeyDown}
        placeholder={placeholder}
        maxLength={maxLength}
        rows={rows}
      />
    </div>
  );
}

export function ProjectModal({ isOpen, onClose, onSave, project }: ProjectModalProps) {
  const [fromMonth, setFromMonth] = useState(1);
  const [fromYear, setFromYear] = useState(currentYear);
  const [toMonth, setToMonth] = useState(1);
  const [toYear, setToYear] = useState(currentYear);
  const [isCurrent, setIsCurrent] = useState(false);
  const [role, setRole] = useState('');
  const [tasks, setTasks] = useState('');
  const [company, setCompany] = useState('');
  const [companySize, setCompanySize] = useState('');
  const [industry, setIndustry] = useState('');
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState('');

  useEffect(() => {
    if (isOpen) {
      if (project) {
        setFromMonth(project.fromMonth);
        setFromYear(project.fromYear);
        setToMonth(project.toMonth ?? 1);
        setToYear(project.toYear ?? currentYear);
        setIsCurrent(project.isCurrent);
        setRole(project.role);
        setTasks(project.tasks ?? '');
        setCompany(project.company ?? '');
        setCompanySize(project.companySize ?? '');
        setIndustry(project.industry ?? '');
      } else {
        setFromMonth(1);
        setFromYear(currentYear);
        setToMonth(1);
        setToYear(currentYear);
        setIsCurrent(false);
        setRole('');
        setTasks('');
        setCompany('');
        setCompanySize('');
        setIndustry('');
      }
      setError('');
    }
  }, [isOpen, project]);

  const handleSubmit = async (e: FormEvent) => {
    e.preventDefault();
    setLoading(true);
    setError('');

    const payload = {
      fromMonth,
      fromYear,
      ...(!isCurrent && { toMonth, toYear }),
      isCurrent,
      role: role.trim(),
      ...(tasks.trim() && { tasks: tasks.trim() }),
      ...(company.trim() && { company: company.trim() }),
      ...(companySize && { companySize }),
      ...(industry && { industry }),
    };

    try {
      if (project) {
        await api.patch(`/expert-profile/me/projects/${project.id}`, payload);
      } else {
        await api.post('/expert-profile/me/projects', payload);
      }
      await onSave();
    } catch (err: unknown) {
      const apiErr = err as { response?: { data?: { message?: string } } };
      setError(apiErr.response?.data?.message ?? 'Fehler beim Speichern');
    } finally {
      setLoading(false);
    }
  };

  return (
    <Modal
      isOpen={isOpen}
      onClose={onClose}
      title={project ? 'Projekt bearbeiten' : 'Neues Projekt hinzufügen'}
      maxWidth="650px"
    >
      <form onSubmit={handleSubmit} className={styles.modalForm}>
        {error && <div className={styles.error}>{error}</div>}

        {/* Zeitraum von */}
        <div className={styles.modalFieldRow}>
          <div className={styles.modalField}>
            <label>Zeitraum von *</label>
            <div style={{ display: 'flex', gap: '0.5rem' }}>
              <select value={fromMonth} onChange={(e) => setFromMonth(Number(e.target.value))} required>
                {MONTHS.map((m) => (
                  <option key={m.value} value={m.value}>{m.label}</option>
                ))}
              </select>
              <select value={fromYear} onChange={(e) => setFromYear(Number(e.target.value))} required>
                {YEARS.map((y) => (
                  <option key={y} value={y}>{y}</option>
                ))}
              </select>
            </div>
          </div>
          <div className={styles.modalField}>
            <label>Zeitraum bis *</label>
            <div style={{ display: 'flex', gap: '0.5rem' }}>
              <select
                value={toMonth}
                onChange={(e) => setToMonth(Number(e.target.value))}
                disabled={isCurrent}
              >
                {MONTHS.map((m) => (
                  <option key={m.value} value={m.value}>{m.label}</option>
                ))}
              </select>
              <select
                value={toYear}
                onChange={(e) => setToYear(Number(e.target.value))}
                disabled={isCurrent}
              >
                {YEARS.map((y) => (
                  <option key={y} value={y}>{y}</option>
                ))}
              </select>
            </div>
          </div>
        </div>

        <div className={styles.checkboxRow}>
          <input
            type="checkbox"
            id="isCurrent"
            checked={isCurrent}
            onChange={(e) => setIsCurrent(e.target.checked)}
          />
          <label htmlFor="isCurrent">bis heute</label>
        </div>

        <div className={styles.modalField}>
          <label>Tätigkeit *</label>
          <input
            type="text"
            value={role}
            onChange={(e) => setRole(e.target.value)}
            placeholder="z.B. Senior DevOps Engineer"
            maxLength={200}
            required
          />
        </div>

        <div className={styles.modalField}>
          <label>Aufgaben</label>
          <BulletEditor
            value={tasks}
            onChange={setTasks}
            placeholder="Beschreiben Sie Ihre Aufgaben... (☰ Liste für Aufzählungspunkte)"
            maxLength={1500}
            rows={6}
          />
          <div className={`${styles.charCount} ${tasks.length > 1400 ? styles.charCountWarn : ''}`}>
            {tasks.length}/1.500
          </div>
        </div>

        <div className={styles.modalField}>
          <label>Firma</label>
          <input
            type="text"
            value={company}
            onChange={(e) => setCompany(e.target.value)}
            placeholder="Firmenname"
            maxLength={200}
          />
        </div>

        <div className={styles.modalFieldRow}>
          <div className={styles.modalField}>
            <label>Unternehmensgröße</label>
            <select value={companySize} onChange={(e) => setCompanySize(e.target.value)}>
              <option value="">Anzahl der Mitarbeitenden</option>
              {COMPANY_SIZES.map((s) => (
                <option key={s} value={s}>{s}</option>
              ))}
            </select>
          </div>
          <div className={styles.modalField}>
            <label>Branche</label>
            <select value={industry} onChange={(e) => setIndustry(e.target.value)}>
              <option value="">Bitte wählen</option>
              {INDUSTRIES.map((ind) => (
                <option key={ind} value={ind}>{ind}</option>
              ))}
            </select>
          </div>
        </div>

        <div className={styles.btnRow}>
          <button type="button" className={styles.btnSecondary} onClick={onClose}>
            Abbrechen
          </button>
          <button type="submit" className={styles.btnPrimary} disabled={loading || !role.trim()}>
            {loading ? 'Speichern...' : project ? 'Projekt speichern' : 'Projekt hinzufügen'}
          </button>
        </div>
      </form>
    </Modal>
  );
}
