import React, { useEffect, useMemo, useState } from 'react';
import {
  DndContext, closestCenter, KeyboardSensor, PointerSensor, useSensor, useSensors,
} from '@dnd-kit/core';
import {
  arrayMove, SortableContext, sortableKeyboardCoordinates, verticalListSortingStrategy, useSortable,
} from '@dnd-kit/sortable';
import { CSS } from '@dnd-kit/utilities';
import { ruleTemplates } from '../templates/ruleTemplates.js';
import { ruleErrors, hasErrors } from '../utils/validation.js';
import { RuleEditorDrawer } from './RuleEditorDrawer.jsx';
import { RouteChecker } from './RouteChecker.jsx';
import { api } from '../api.js';

const OUTBOUND_KIND = {
  direct: { kind: 'success', label: 'direct' },
  vpn:    { kind: 'info',    label: 'VPN' },
  block:  { kind: 'danger',  label: 'block' },
};

function summary(rule) {
  const parts = [];
  const totalDomains = (rule.domains?.length || 0) + (rule.domainSuffixes?.length || 0) + (rule.domainKeywords?.length || 0);
  if (totalDomains) parts.push(`${totalDomains} дом.`);
  if (rule.ipCidrs?.length) parts.push(`${rule.ipCidrs.length} CIDR`);
  if (rule.ports?.length) parts.push(`${rule.ports.length} портов`);
  if (rule.networks?.length) parts.push(rule.networks.join('/'));
  return parts.join(' · ') || '—';
}

function SortableRuleRow({ rule, index, total, onEdit, onUpdate, onRemove, conflict }) {
  const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({ id: rule.id });
  const style = { transform: CSS.Transform.toString(transform), transition, opacity: isDragging ? 0.5 : 1 };
  const errors = ruleErrors(rule);
  const invalid = hasErrors(errors);
  const ob = OUTBOUND_KIND[rule.outbound] || OUTBOUND_KIND.direct;

  return (
    <tr ref={setNodeRef} style={style} className={`rule-row ${rule.enabled ? '' : 'disabled'} ${invalid ? 'invalid' : ''}`}>
      <td style={{ width: 30 }}>
        <span className="drag-handle" {...attributes} {...listeners} title="Перетащить">⠿</span>
      </td>
      <td style={{ width: 36 }} className="muted text-mono">#{index + 1}</td>
      <td>
        <div className="flex" style={{ alignItems: 'center' }}>
          <input
            type="checkbox"
            checked={rule.enabled !== false}
            onChange={(e) => onUpdate(rule.id, { enabled: e.target.checked })}
            style={{ accentColor: 'var(--accent)' }}
          />
          <button className="btn btn-link" style={{ padding: 0, fontWeight: 600 }} onClick={() => onEdit(rule.id)}>
            {rule.name || '(без названия)'}
          </button>
          {invalid && <span className="badge danger">ошибки</span>}
          {conflict && <span className={`badge ${conflict.severity === 'warning' ? 'warning' : 'info'}`} title={`Перекрывается с #${conflict.conflictWithIndex + 1}`}>конфликт</span>}
        </div>
      </td>
      <td><span className={`badge ${ob.kind}`}>{ob.label}</span></td>
      <td className="muted" style={{ fontSize: 12 }}>{summary(rule)}</td>
      <td style={{ textAlign: 'right' }}>
        <div className="row-actions">
          <button className="btn btn-ghost sm" onClick={() => onEdit(rule.id)}>Редактировать</button>
          <button className="btn btn-ghost sm" onClick={() => { if (confirm('Удалить правило?')) onRemove(rule.id); }}>×</button>
        </div>
      </td>
    </tr>
  );
}

function TemplatesModal({ open, onClose, onAdd }) {
  if (!open) return null;
  return (
    <div className="modal-backdrop" onClick={onClose}>
      <div className="modal lg" onClick={(e) => e.stopPropagation()}>
        <div className="modal-head">
          <h3>Шаблоны маршрутизации</h3>
          <button className="btn btn-ghost sm" onClick={onClose}>Закрыть</button>
        </div>
        <div className="modal-body">
          <div className="template-grid">
            {ruleTemplates.map((tpl) => (
              <div key={tpl.key} className="template-card">
                <h4>{tpl.label}</h4>
                <small>{tpl.description}</small>
                <button className="btn btn-secondary sm" onClick={() => { onAdd(tpl.build()); onClose(); }}>
                  + Добавить
                </button>
              </div>
            ))}
          </div>
        </div>
      </div>
    </div>
  );
}

export function RoutingPage({
  rules, saveStatus, busy,
  onAdd, onAddTemplate, onUpdate, onRemove, onSaveNow, onReorder,
}) {
  const [editingId, setEditingId] = useState(null);
  const [showTemplates, setShowTemplates] = useState(false);
  const [conflicts, setConflicts] = useState([]);
  const sensors = useSensors(
    useSensor(PointerSensor, { activationConstraint: { distance: 5 } }),
    useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates }),
  );

  useEffect(() => {
    let cancelled = false;
    const t = setTimeout(() => {
      api.rules.conflicts().then((data) => { if (!cancelled) setConflicts(data.conflicts || []); }).catch(() => {});
    }, 600);
    return () => { cancelled = true; clearTimeout(t); };
  }, [rules]);

  const conflictsByRuleId = useMemo(() => {
    const map = {};
    for (const c of conflicts) map[c.ruleId] = c;
    return map;
  }, [conflicts]);

  function handleDragEnd(event) {
    const { active, over } = event;
    if (!over || active.id === over.id) return;
    const oldIndex = rules.findIndex((r) => r.id === active.id);
    const newIndex = rules.findIndex((r) => r.id === over.id);
    if (oldIndex < 0 || newIndex < 0) return;
    onReorder(arrayMove(rules, oldIndex, newIndex));
  }

  const editing = rules.find((r) => r.id === editingId) || null;

  return (
    <div className="section-stack">
      <RouteChecker />

      <div className="card">
        <div className="card-header">
          <h2>Правила маршрутизации</h2>
          <div className="btn-group">
            <button className="btn btn-secondary sm" onClick={() => setShowTemplates(true)}>Шаблоны</button>
            <button className="btn btn-primary sm" onClick={() => { const newId = `rule-${Date.now()}`; onAdd(); setTimeout(() => setEditingId(newId), 50); }}>
              + Добавить
            </button>
          </div>
        </div>

        {conflicts.length > 0 && (
          <div className="conflict-banner" style={{ marginBottom: 12 }}>
            <span>⚠</span>
            <div>
              <strong>{conflicts.length} конфликт(ов) обнаружено</strong>
              <div style={{ marginTop: 4 }}>
                {conflicts.slice(0, 3).map((c, i) => (
                  <div key={i} style={{ fontSize: 12 }}>
                    #{c.ruleIndex + 1} «{c.ruleName}» перекрывается правилом #{c.conflictWithIndex + 1} «{c.conflictWithName}»
                  </div>
                ))}
              </div>
            </div>
          </div>
        )}

        <small className="muted" style={{ display: 'block', marginBottom: 8 }}>
          Применяются <strong>сверху вниз</strong>. Перетаскивай ⠿ чтобы менять порядок.
        </small>

        {rules.length === 0 ? (
          <div className="empty-state">
            <h3>Правил пока нет</h3>
            <p>Добавь шаблон (например «League of Legends → direct») или создай пустое правило.</p>
            <button className="btn btn-primary" onClick={() => setShowTemplates(true)} style={{ marginTop: 12 }}>
              Открыть шаблоны
            </button>
          </div>
        ) : (
          <div style={{ overflowX: 'auto' }}>
            <table className="table">
              <thead>
                <tr>
                  <th></th>
                  <th>#</th>
                  <th>Правило</th>
                  <th>Outbound</th>
                  <th>Условия</th>
                  <th></th>
                </tr>
              </thead>
              <tbody>
                <DndContext sensors={sensors} collisionDetection={closestCenter} onDragEnd={handleDragEnd}>
                  <SortableContext items={rules.map((r) => r.id)} strategy={verticalListSortingStrategy}>
                    {rules.map((rule, i) => (
                      <SortableRuleRow
                        key={rule.id}
                        rule={rule}
                        index={i}
                        total={rules.length}
                        onEdit={setEditingId}
                        onUpdate={onUpdate}
                        onRemove={onRemove}
                        conflict={conflictsByRuleId[rule.id]}
                      />
                    ))}
                  </SortableContext>
                </DndContext>
              </tbody>
            </table>
          </div>
        )}
      </div>

      <RuleEditorDrawer
        rule={editing}
        onUpdate={onUpdate}
        onClose={() => setEditingId(null)}
        onRemove={onRemove}
      />
      <TemplatesModal open={showTemplates} onClose={() => setShowTemplates(false)} onAdd={onAddTemplate} />
    </div>
  );
}
