import React, { useState, useCallback } from 'react';
import {
  DndContext, DragOverlay, closestCorners,
  PointerSensor, useSensor, useSensors,
} from '@dnd-kit/core';
import { SortableContext, verticalListSortingStrategy, useSortable } from '@dnd-kit/sortable';
import { CSS } from '@dnd-kit/utilities';
import { projectsService } from '../../services/projects.service';
import { MOCK_TEAM } from '../../services/mockData';

// ── Column definitions ────────────────────────────────────────────────────────
const COLUMNS = [
  { id:'PENDIENTE',       label:'Pendiente',        color:'border-slate-400 dark:border-gray-600',  canAdd:true  },
  { id:'EN_PROCESO',      label:'En proceso',        color:'border-blue-500',                        canAdd:true  },
  { id:'BLOQUEADA',       label:'Bloqueada',         color:'border-red-500',                         canAdd:false },
  { id:'EN_VERIFICACION', label:'Inspección QC',     color:'border-amber-400',                       canAdd:false },
  { id:'COMPLETADA',      label:'Completada',        color:'border-emerald-500',                     canAdd:false },
];

// Status transitions allowed (who can move where from current)
const ALLOWED_TRANSITIONS = {
  PENDIENTE:       ['EN_PROCESO','BLOQUEADA'],
  EN_PROCESO:      ['EN_VERIFICACION','BLOQUEADA','PENDIENTE'],
  EN_VERIFICACION: ['COMPLETADA','EN_PROCESO','BLOQUEADA'],
  BLOQUEADA:       ['PENDIENTE','EN_PROCESO'],
  COMPLETADA:      [], // locked — can only reopen via edit modal
};

// Genera una tarea de inspección QC vinculada a la tarea completada
function createQCTask(originalTask, projectId) {
  const slaDays = 2; // SLA por defecto: 2 días para inspeccionar
  const dueDate = originalTask.dueDate
    ? new Date(new Date(originalTask.dueDate).getTime() + slaDays * 86400000).toISOString().slice(0,10)
    : '';
  return {
    id: `qc-${originalTask.id}-${Date.now()}`,
    title: `Inspección QC: ${originalTask.title}`,
    status: 'EN_VERIFICACION',
    priority: originalTask.priority || 'MEDIO',
    isQCTask: true,
    linkedTaskId: originalTask.id,
    linkedTaskTitle: originalTask.title,
    wbsCode: originalTask.wbsCode ? `${originalTask.wbsCode}.QC` : 'QC',
    phase: originalTask.phase || '',
    estimatedHours: Math.max(2, Math.round((originalTask.estimatedHours || 4) * 0.2)),
    actualHours: 0,
    progressPct: 0,
    assignee: null, // inspector asignará desde QC
    dueDate,
    createdAt: new Date().toISOString(),
    qcResult: null, // 'APROBADO' | 'RECHAZADO' | null
  };
}

const PRIORITY_CFG = {
  CRITICO: { badge:'bg-red-100 text-red-700 dark:bg-red-500/20 dark:text-red-400',           dot:'bg-red-500'    },
  ALTO:    { badge:'bg-orange-100 text-orange-700 dark:bg-orange-500/20 dark:text-orange-400', dot:'bg-orange-400' },
  MEDIO:   { badge:'bg-amber-100 text-amber-700 dark:bg-amber-500/20 dark:text-amber-400',    dot:'bg-amber-400'  },
  BAJO:    { badge:'bg-slate-100 text-slate-500 dark:bg-gray-500/20 dark:text-gray-400',      dot:'bg-slate-400'  },
};

const PRIORITIES = ['CRITICO','ALTO','MEDIO','BAJO'];

// Compute resource cost for a task (estimatedHours × hourly rate)
function calcResourceCost(assignee, estimatedHours) {
  if (!assignee || !estimatedHours) return null;
  const m = MOCK_TEAM.find(t => t.id === assignee.id || t.id === assignee);
  if (!m) return null;
  let ratePerHour = 0;
  if (m.costType === 'HORA') ratePerHour = m.costRate;
  else if (m.costType === 'MES') ratePerHour = m.costRate / (m.hoursPerDay * m.daysPerWeek * 4.33);
  else if (m.costType === 'DIA') ratePerHour = m.costRate / m.hoursPerDay;
  return ratePerHour * estimatedHours;
}

const fmtCost = n => n >= 1000 ? `$${(n/1000).toFixed(1)}K` : `$${Math.round(n)}`;

// ── Task Modal ────────────────────────────────────────────────────────────────
function TaskModal({ task, defaultStatus, projectTasks, onSave, onClose }) {
  const editing = !!task;

  const [form, setForm] = useState(() => task ? {
    title:          task.title || '',
    priority:       task.priority || 'MEDIO',
    dueDate:        task.dueDate || '',
    status:         task.status || defaultStatus,
    assigneeId:     task.assignee?.id || '',
    estimatedHours: task.estimatedHours || '',
    actualHours:    task.actualHours || '',
    progressPct:    task.progressPct ?? '',
    predecessors:   task.predecessors || [],
    blockedReason:  task.blockedReason || '',
    authorizedById: task.authorizedBy?.id || '',
    qcResult:       task.qcResult || '',
    ncDescription:  task.ncDescription || '',
  } : {
    title:'', priority:'MEDIO', dueDate:'', status: defaultStatus || 'PENDIENTE',
    assigneeId:'', estimatedHours:'', actualHours:'', progressPct:'',
    predecessors:[], blockedReason:'', authorizedById:'', qcResult:'', ncDescription:'',
  });

  const [err, setErr] = useState('');
  const [saving, setSaving] = useState(false);

  const set = (k, v) => setForm(f => ({ ...f, [k]: v }));

  const assignee   = MOCK_TEAM.find(m => m.id === form.assigneeId) || null;
  const estCost    = calcResourceCost(assignee, Number(form.estimatedHours));
  const isBlocked  = form.status === 'BLOQUEADA';
  const isProgress = ['EN_PROCESO','EN_VERIFICACION'].includes(form.status);
  const isComplete = form.status === 'COMPLETADA';
  const wasComplete = task?.status === 'COMPLETADA';

  const estH   = Number(form.estimatedHours) || 0;
  const actH   = Number(form.actualHours)    || 0;
  const overrun = isComplete && estH > 0 && actH > estH;
  const pctDiff = estH > 0 ? Math.round(((actH - estH) / estH) * 100) : 0;

  const handleSubmit = async e => {
    e.preventDefault();
    if (!form.title.trim()) { setErr('El título es requerido'); return; }
    if (isBlocked && !form.blockedReason.trim()) { setErr('Ingresa el motivo del bloqueo'); return; }
    if (isBlocked && !form.authorizedById) { setErr('Selecciona quién autorizó el bloqueo'); return; }
    if (isComplete && !wasComplete && !form.actualHours) { setErr('Ingresa las horas reales trabajadas para completar la tarea'); return; }
    if (overrun && !form.overrunReason?.trim()) { setErr('Explica por qué se excedieron las horas estimadas'); return; }
    setSaving(true);
    const payload = {
      ...form,
      assignee: assignee || null,
      authorizedBy: MOCK_TEAM.find(m => m.id === form.authorizedById) || null,
      estimatedHours: Number(form.estimatedHours) || 0,
      actualHours:    Number(form.actualHours)    || 0,
      progressPct:    isComplete ? 100 : (Number(form.progressPct) || 0),
      plannedCost:    estCost || task?.plannedCost || 0,
    };
    await onSave(payload);
    setSaving(false);
  };

  // Allowed statuses when editing
  const statusOptions = editing
    ? COLUMNS.filter(c =>
        c.id === task.status ||
        (ALLOWED_TRANSITIONS[task.status] || []).includes(c.id) ||
        (task.status === 'COMPLETADA') // show all when reopening
      )
    : COLUMNS.filter(c => ['PENDIENTE','EN_PROCESO'].includes(c.id));

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center p-4">
      <div className="absolute inset-0 bg-black/40 backdrop-blur-sm" onClick={onClose}/>
      <div className="relative w-full max-w-lg bg-white dark:bg-surface-800 rounded-2xl shadow-2xl border border-slate-200 dark:border-surface-700 overflow-hidden max-h-[90vh] flex flex-col">

        {/* Header */}
        <div className="flex items-center justify-between px-5 py-4 border-b border-slate-100 dark:border-surface-700 flex-shrink-0">
          <div>
            <h2 className="text-sm font-semibold text-slate-900 dark:text-white">
              {editing ? 'Editar tarea' : 'Nueva tarea'}
            </h2>
            {editing && <p className="text-xs text-slate-400 dark:text-gray-500 mt-0.5">{task.wbsCode} · {task.phase}</p>}
          </div>
          <button onClick={onClose} className="p-1.5 rounded-lg text-slate-400 hover:text-slate-600 dark:hover:text-white hover:bg-slate-100 dark:hover:bg-surface-700 transition cursor-pointer">
            <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}><path strokeLinecap="round" strokeLinejoin="round" d="M6 18L18 6M6 6l12 12"/></svg>
          </button>
        </div>

        <form onSubmit={handleSubmit} className="overflow-y-auto flex-1">
          <div className="p-5 space-y-4">

            {/* Title */}
            <div>
              <label className="field-label">Título *</label>
              <input autoFocus value={form.title} onChange={e=>set('title',e.target.value)}
                placeholder="Describe la tarea..."
                className="field-input"/>
              {err && <p className="text-xs text-red-500 mt-1">{err}</p>}
            </div>

            {/* Priority */}
            <div>
              <label className="field-label">Prioridad</label>
              <div className="grid grid-cols-4 gap-2">
                {PRIORITIES.map(p => {
                  const cfg = PRIORITY_CFG[p];
                  return (
                    <button type="button" key={p} onClick={()=>set('priority',p)}
                      className={`py-2 rounded-xl text-xs font-semibold border transition cursor-pointer ${
                        form.priority===p ? `${cfg.badge} border-current` : 'border-slate-200 dark:border-surface-600 text-slate-400 dark:text-gray-500 hover:border-slate-300'
                      }`}>
                      {p.charAt(0)+p.slice(1).toLowerCase()}
                    </button>
                  );
                })}
              </div>
            </div>

            {/* Status (only edit) */}
            {editing && (
              <div>
                <label className="field-label">Estado</label>
                <select value={form.status} onChange={e=>set('status',e.target.value)}
                  className="field-input cursor-pointer">
                  {statusOptions.map(c=><option key={c.id} value={c.id}>{c.label}</option>)}
                </select>
                {task.status==='COMPLETADA' && form.status!=='COMPLETADA' && (
                  <p className="text-xs text-amber-600 dark:text-amber-400 mt-1">⚠ Estás reabriendo una tarea completada</p>
                )}
              </div>
            )}

            {/* Assignee + cost preview */}
            <div>
              <label className="field-label">Responsable (recurso)</label>
              <select value={form.assigneeId} onChange={e=>set('assigneeId',e.target.value)}
                className="field-input cursor-pointer">
                <option value="">— Sin asignar —</option>
                {MOCK_TEAM.map(m=>(
                  <option key={m.id} value={m.id}>
                    {m.firstName} {m.lastName} · {m.title} · {m.costType==='HORA'?`$${m.costRate}/hr`:m.costType==='MES'?`$${m.costRate.toLocaleString()}/mes`:`$${m.costRate}`}
                  </option>
                ))}
              </select>
              {assignee && (
                <div className="mt-1.5 flex items-center gap-3 text-xs text-slate-400 dark:text-gray-500">
                  <span className="flex items-center gap-1">
                    <svg className="w-3 h-3" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}><circle cx="12" cy="12" r="10"/><path strokeLinecap="round" strokeLinejoin="round" d="M12 6v6l4 2"/></svg>
                    {assignee.hoursPerDay}h/día · {assignee.daysPerWeek} días/sem
                  </span>
                  <span>{assignee.startTime}–{assignee.endTime}</span>
                  {estCost && <span className="ml-auto text-blue-600 dark:text-blue-400 font-semibold">{fmtCost(estCost)} est.</span>}
                </div>
              )}
            </div>

            {/* Hours */}
            <div className="grid grid-cols-2 gap-3">
              <div>
                <label className="field-label">Horas estimadas</label>
                <input type="number" min="0" step="0.5" value={form.estimatedHours}
                  onChange={e=>set('estimatedHours',e.target.value)}
                  placeholder="0"
                  className="field-input"/>
              </div>
              <div>
                <label className="field-label">
                  Horas reales {isComplete && !wasComplete && <span className="text-red-500">*</span>}
                </label>
                <input type="number" min="0" step="0.5" value={form.actualHours}
                  onChange={e=>set('actualHours',e.target.value)}
                  placeholder="0"
                  className={`field-input ${isComplete && !wasComplete && !form.actualHours ? 'border-red-400 dark:border-red-500' : ''}`}/>
              </div>
            </div>

            {/* Panel de cierre — solo al completar */}
            {isComplete && !wasComplete && (
              <div className={`rounded-xl border p-4 space-y-3 ${overrun ? 'bg-red-50 dark:bg-red-500/10 border-red-200 dark:border-red-500/30' : 'bg-emerald-50 dark:bg-emerald-500/10 border-emerald-200 dark:border-emerald-500/30'}`}>
                <div className="flex items-center gap-2">
                  {overrun
                    ? <><svg className="w-4 h-4 text-red-500 flex-shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}><path strokeLinecap="round" strokeLinejoin="round" d="M12 9v2m0 4h.01M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z"/></svg>
                       <p className="text-xs font-bold text-red-700 dark:text-red-400">Exceso de horas: +{actH - estH}h ({pctDiff > 0 ? '+' : ''}{pctDiff}% sobre el estimado)</p></>
                    : <><svg className="w-4 h-4 text-emerald-600 flex-shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}><path strokeLinecap="round" strokeLinejoin="round" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
                       <p className="text-xs font-bold text-emerald-700 dark:text-emerald-400">
                         {actH > 0 && estH > 0 ? `Dentro del estimado (${estH - actH}h de margen, ${Math.abs(pctDiff)}% mejor)` : 'Tarea completada'}
                       </p></>
                  }
                </div>
                {overrun && (
                  <div>
                    <label className="field-label">¿Por qué se excedieron las horas? <span className="text-red-500">*</span></label>
                    <textarea rows={2} value={form.overrunReason || ''} onChange={e=>set('overrunReason',e.target.value)}
                      placeholder="Ej: Requisitos adicionales del cliente, problemas técnicos imprevistos..."
                      className="field-input resize-none text-xs"/>
                  </div>
                )}
                {actH > 0 && estH > 0 && (
                  <div className="grid grid-cols-3 gap-2 text-center">
                    {[
                      { label:'Estimado', val:`${estH}h`, color:'text-slate-600 dark:text-gray-400' },
                      { label:'Real', val:`${actH}h`, color: overrun ? 'text-red-600 dark:text-red-400 font-bold' : 'text-emerald-600 dark:text-emerald-400 font-bold' },
                      { label:'Costo real', val: assignee ? fmtCost(calcResourceCost(assignee, actH)) : '—', color:'text-blue-600 dark:text-blue-400' },
                    ].map(k => (
                      <div key={k.label} className="bg-white/60 dark:bg-black/20 rounded-lg py-2">
                        <p className="text-xs text-slate-400 dark:text-gray-500">{k.label}</p>
                        <p className={`text-sm ${k.color}`}>{k.val}</p>
                      </div>
                    ))}
                  </div>
                )}
              </div>
            )}

            {/* Progress (only for active tasks) */}
            {(isProgress || editing) && !isComplete && (
              <div>
                <div className="flex items-center justify-between mb-1.5">
                  <label className="field-label mb-0">Avance</label>
                  <span className="text-sm font-bold text-blue-600 dark:text-blue-400 tabular-nums">{form.progressPct || 0}%</span>
                </div>
                <input type="range" min="0" max="100" step="5"
                  value={form.progressPct || 0}
                  onChange={e=>set('progressPct', Number(e.target.value))}
                  className="w-full h-2 rounded-full appearance-none cursor-pointer bg-slate-200 dark:bg-surface-600 accent-blue-600"/>
                <div className="flex justify-between text-xs text-slate-300 dark:text-gray-600 mt-0.5">
                  <span>0%</span><span>25%</span><span>50%</span><span>75%</span><span>100%</span>
                </div>
              </div>
            )}

            {/* Predecessors */}
            {projectTasks && projectTasks.length > 0 && (
              <div>
                <label className="field-label">Predecesoras</label>
                <div className="max-h-28 overflow-y-auto space-y-1 border border-slate-200 dark:border-surface-600 rounded-xl p-2">
                  {projectTasks.filter(t=>t.id !== task?.id).map(t=>{
                    const selected = form.predecessors.some(p=>p.id===t.id);
                    return (
                      <label key={t.id} className="flex items-center gap-2 cursor-pointer hover:bg-slate-50 dark:hover:bg-surface-700 rounded-lg px-2 py-1 transition">
                        <input type="checkbox" checked={selected}
                          onChange={e=>{
                            if(e.target.checked) set('predecessors',[...form.predecessors,{id:t.id,type:'FS',lag:0}]);
                            else set('predecessors', form.predecessors.filter(p=>p.id!==t.id));
                          }}
                          className="rounded accent-blue-600"/>
                        <span className="text-xs font-mono text-slate-400 dark:text-gray-500 w-8">{t.wbsCode}</span>
                        <span className="text-xs text-slate-700 dark:text-gray-300 truncate">{t.title}</span>
                      </label>
                    );
                  })}
                </div>
              </div>
            )}

            {/* Due date */}
            <div>
              <label className="field-label">Fecha límite</label>
              <input type="date" value={form.dueDate} onChange={e=>set('dueDate',e.target.value)}
                className="field-input"/>
            </div>

            {/* Block reason (only when BLOQUEADA) */}
            {isBlocked && (
              <div className="rounded-xl bg-red-50 dark:bg-red-500/10 border border-red-200 dark:border-red-500/30 p-4 space-y-3">
                <p className="text-xs font-bold text-red-600 dark:text-red-400 uppercase tracking-wider">Información de bloqueo</p>
                <div>
                  <label className="field-label">Motivo del bloqueo *</label>
                  <textarea rows={2} value={form.blockedReason} onChange={e=>set('blockedReason',e.target.value)}
                    placeholder="Describe el impedimento..."
                    className="field-input resize-none"/>
                </div>
                <div>
                  <label className="field-label">Autorizado por *</label>
                  <select value={form.authorizedById} onChange={e=>set('authorizedById',e.target.value)}
                    className="field-input cursor-pointer">
                    <option value="">— Seleccionar responsable —</option>
                    {MOCK_TEAM.filter(m=>['SUPER_ADMIN','DIRECTOR','GERENTE','JEFE_AREA'].includes(m.role)).map(m=>(
                      <option key={m.id} value={m.id}>{m.firstName} {m.lastName} · {m.title}</option>
                    ))}
                  </select>
                </div>
              </div>
            )}

            {/* Panel QC — solo para tareas de inspección */}
            {task?.isQCTask && (
              <div className="rounded-xl border border-amber-200 dark:border-amber-500/30 bg-amber-50 dark:bg-amber-500/10 p-4 space-y-3">
                <div className="flex items-center gap-2">
                  <svg className="w-4 h-4 text-amber-600 dark:text-amber-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}><path strokeLinecap="round" strokeLinejoin="round" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
                  <p className="text-xs font-bold text-amber-700 dark:text-amber-400 uppercase tracking-wider">Inspección QC</p>
                </div>
                <p className="text-xs text-amber-700 dark:text-amber-300">
                  Tarea inspeccionada: <span className="font-semibold">{task.linkedTaskTitle}</span>
                </p>
                <div>
                  <label className="field-label">Resultado de la inspección</label>
                  <div className="grid grid-cols-2 gap-2">
                    {[
                      { val:'APROBADO', label:'✓ Aprobado', cls:'bg-emerald-100 text-emerald-700 dark:bg-emerald-500/20 dark:text-emerald-400 border-emerald-400' },
                      { val:'RECHAZADO', label:'✗ Rechazado — NCR', cls:'bg-red-100 text-red-700 dark:bg-red-500/20 dark:text-red-400 border-red-400' },
                    ].map(opt => (
                      <button type="button" key={opt.val}
                        onClick={() => set('qcResult', opt.val)}
                        className={`py-2.5 rounded-xl text-xs font-bold border-2 transition cursor-pointer ${
                          form.qcResult === opt.val ? opt.cls : 'border-slate-200 dark:border-surface-600 text-slate-400 dark:text-gray-500'
                        }`}>
                        {opt.label}
                      </button>
                    ))}
                  </div>
                </div>
                {form.qcResult === 'RECHAZADO' && (
                  <div>
                    <label className="field-label">Descripción de no conformidad</label>
                    <textarea rows={2} value={form.ncDescription || ''} onChange={e => set('ncDescription', e.target.value)}
                      placeholder="Describe el defecto o incumplimiento encontrado..."
                      className="field-input resize-none text-xs"/>
                    <p className="text-xs text-red-600 dark:text-red-400 font-medium mt-1">
                      ⚠ La tarea original volverá a "En proceso" con NCR abierto
                    </p>
                  </div>
                )}
                {form.qcResult === 'APROBADO' && (
                  <p className="text-xs text-emerald-700 dark:text-emerald-400 font-medium">
                    ✓ La tarea quedará aceptada — habilitada para pago
                  </p>
                )}
              </div>
            )}

            {/* Cost summary */}
            {(form.estimatedHours || form.actualHours) && assignee && (
              <div className="rounded-xl bg-blue-50 dark:bg-blue-500/10 border border-blue-100 dark:border-blue-500/20 p-3">
                <p className="text-xs font-semibold text-blue-700 dark:text-blue-400 mb-2">Resumen de costo del recurso</p>
                <div className="grid grid-cols-2 gap-2 text-xs">
                  <div><span className="text-slate-400 dark:text-gray-500">Tarifa:</span> <span className="font-semibold text-slate-700 dark:text-gray-200">{assignee.costType==='HORA'?`$${assignee.costRate}/hr`:assignee.costType==='MES'?`$${assignee.costRate.toLocaleString()}/mes`:`$${assignee.costRate}`}</span></div>
                  {estCost && <div><span className="text-slate-400 dark:text-gray-500">Costo planeado:</span> <span className="font-bold text-blue-700 dark:text-blue-400">{fmtCost(estCost)}</span></div>}
                  {form.actualHours && <div><span className="text-slate-400 dark:text-gray-500">Costo real:</span> <span className={`font-bold ${calcResourceCost(assignee,Number(form.actualHours))>estCost?'text-red-600 dark:text-red-400':'text-emerald-600 dark:text-emerald-400'}`}>{fmtCost(calcResourceCost(assignee,Number(form.actualHours)))}</span></div>}
                  <div><span className="text-slate-400 dark:text-gray-500">Horario:</span> <span className="font-semibold text-slate-700 dark:text-gray-200">{assignee.startTime}–{assignee.endTime}</span></div>
                </div>
              </div>
            )}
          </div>

          {/* Footer actions */}
          <div className="px-5 pb-5 flex gap-2 flex-shrink-0">
            <button type="button" onClick={onClose}
              className="flex-1 py-2.5 text-sm font-medium rounded-xl border border-slate-200 dark:border-surface-600 text-slate-600 dark:text-gray-300 hover:bg-slate-50 dark:hover:bg-surface-700 transition cursor-pointer">
              Cancelar
            </button>
            <button type="submit" disabled={saving}
              className="flex-1 py-2.5 text-sm font-medium rounded-xl bg-blue-600 hover:bg-blue-700 text-white transition cursor-pointer disabled:opacity-50 flex items-center justify-center gap-2">
              {saving && <span className="w-3.5 h-3.5 border-2 border-white/40 border-t-white rounded-full animate-spin"/>}
              {editing ? 'Guardar cambios' : 'Crear tarea'}
            </button>
          </div>
        </form>
      </div>
    </div>
  );
}

// ── Task Card ─────────────────────────────────────────────────────────────────
function TaskCard({ task, isDragging, onEdit }) {
  const { attributes, listeners, setNodeRef, transform, transition } = useSortable({ id: task.id });
  const style = { transform: CSS.Transform.toString(transform), transition, opacity: isDragging ? 0.3 : 1 };
  const cfg    = PRIORITY_CFG[task.priority] || PRIORITY_CFG.MEDIO;
  const overdue = task.dueDate && new Date(task.dueDate) < new Date() && task.status !== 'COMPLETADA';
  const pct    = task.progressPct ?? 0;
  const estCost = calcResourceCost(task.assignee, task.estimatedHours);

  return (
    <div ref={setNodeRef} style={style} {...attributes}
      className="bg-white dark:bg-surface-700 rounded-xl border border-slate-200 dark:border-surface-600 hover:border-slate-300 dark:hover:border-surface-500 hover:shadow-sm transition-all group select-none">

      <div className="p-3" {...listeners} style={{cursor: task.status==='COMPLETADA' ? 'default' : 'grab'}}>
        {/* Priority dot + title */}
        <div className="flex items-start gap-2 mb-2">
          <span className={`w-1.5 h-1.5 rounded-full flex-shrink-0 mt-1.5 ${cfg.dot}`}/>
          <p className="text-sm text-slate-800 dark:text-white font-medium leading-snug flex-1 line-clamp-2">{task.title}</p>
        </div>

        {/* Progress bar (non-zero) */}
        {pct > 0 && task.status !== 'PENDIENTE' && (
          <div className="mb-2">
            <div className="h-1 bg-slate-100 dark:bg-surface-600 rounded-full overflow-hidden">
              <div className="h-full rounded-full transition-all" style={{width:`${pct}%`, background: pct===100?'#10B981':pct>=75?'#2563EB':'#F59E0B'}}/>
            </div>
            <span className="text-xs text-slate-400 dark:text-gray-500 tabular-nums">{pct}%</span>
          </div>
        )}

        {/* Meta row */}
        <div className="flex items-center justify-between gap-2 flex-wrap">
          <span className={`text-xs px-1.5 py-0.5 rounded font-medium ${cfg.badge}`}>
            {task.priority?.charAt(0)+task.priority?.slice(1).toLowerCase()}
          </span>
          {task.assignee && (
            <span className="text-xs text-slate-400 dark:text-gray-500 truncate max-w-[80px]">
              {task.assignee.firstName} {task.assignee.lastName?.[0]}.
            </span>
          )}
        </div>

        {/* Hours + cost */}
        {(task.estimatedHours > 0) && (
          <div className="flex items-center gap-2 mt-1.5 text-xs text-slate-400 dark:text-gray-500">
            <span>{task.actualHours||0}h/{task.estimatedHours}h</span>
            {estCost && <span className="ml-auto text-blue-500 dark:text-blue-400">{fmtCost(estCost)}</span>}
          </div>
        )}

        {/* Due date */}
        {task.dueDate && (
          <p className={`text-xs mt-1 ${overdue?'text-red-500 font-medium':'text-slate-400 dark:text-gray-500'}`}>
            {overdue?'⚠ ':''}
            {new Date(task.dueDate).toLocaleDateString('es-MX',{day:'2-digit',month:'short'})}
          </p>
        )}

          {/* QC badge */}
        {task.isQCTask && (
          <div className="mt-1.5 flex items-center gap-1.5 text-xs bg-amber-50 dark:bg-amber-500/10 text-amber-700 dark:text-amber-400 rounded-lg px-2 py-1 border border-amber-200 dark:border-amber-500/30">
            <svg className="w-3 h-3 flex-shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}><path strokeLinecap="round" strokeLinejoin="round" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
            <span className="font-semibold">Inspección QC</span>
            <span className="text-amber-500 dark:text-amber-500 truncate">· {task.linkedTaskTitle}</span>
          </div>
        )}

        {/* NCR badge */}
        {task.ncr && (
          <div className="mt-1.5 text-xs bg-red-50 dark:bg-red-500/10 text-red-600 dark:text-red-400 rounded-lg px-2 py-1 border border-red-200 dark:border-red-500/30 font-semibold">
            ⚠ NCR abierto — en corrección
          </div>
        )}

        {/* Block reason badge */}
        {task.status==='BLOQUEADA' && task.blockedReason && (
          <p className="mt-1.5 text-xs text-red-600 dark:text-red-400 bg-red-50 dark:bg-red-500/10 rounded-lg px-2 py-1 leading-snug line-clamp-2">
            🔴 {task.blockedReason}
          </p>
        )}
      </div>

      {/* Edit button */}
      <button
        onPointerDown={e => e.stopPropagation()}
        onClick={e => { e.stopPropagation(); onEdit(task); }}
        className="w-full px-3 py-1.5 text-xs text-slate-400 dark:text-gray-500 hover:text-blue-600 dark:hover:text-blue-400 border-t border-slate-100 dark:border-surface-600 text-left opacity-0 group-hover:opacity-100 transition-opacity cursor-pointer flex items-center gap-1.5">
        <svg className="w-3 h-3" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}><path strokeLinecap="round" strokeLinejoin="round" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"/></svg>
        Editar · actualizar avance
      </button>
    </div>
  );
}

// ── Column ────────────────────────────────────────────────────────────────────
function Column({ column, tasks, onAddTask, onEdit }) {
  const { setNodeRef } = useSortable({ id: column.id });
  const totalHrs  = tasks.reduce((s,t)=>s+(t.estimatedHours||0),0);
  const totalCost = tasks.reduce((s,t)=>s+(calcResourceCost(t.assignee,t.estimatedHours)||0),0);

  return (
    <div ref={setNodeRef}
      className={`flex flex-col bg-slate-50 dark:bg-surface-800 rounded-2xl border-t-2 ${column.color} border border-slate-200 dark:border-surface-700 min-h-64`}>

      {/* Header */}
      <div className="px-3 py-2.5 border-b border-slate-200 dark:border-surface-700">
        <div className="flex items-center justify-between gap-2 mb-1">
          <div className="flex items-center gap-2">
            <h3 className="text-xs font-semibold text-slate-600 dark:text-gray-300 uppercase tracking-wider">{column.label}</h3>
            <span className="text-xs bg-slate-200 dark:bg-surface-600 text-slate-500 dark:text-gray-400 px-1.5 py-0.5 rounded-full">{tasks.length}</span>
          </div>
          {column.canAdd && (
            <button onClick={() => onAddTask(column.id)} title="Agregar tarea"
              className="w-6 h-6 flex items-center justify-center rounded-lg text-slate-400 dark:text-gray-500 hover:text-blue-600 dark:hover:text-blue-400 hover:bg-blue-50 dark:hover:bg-blue-500/10 transition cursor-pointer">
              <svg className="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2.5}><path strokeLinecap="round" strokeLinejoin="round" d="M12 4v16m8-8H4"/></svg>
            </button>
          )}
        </div>
        {/* Column totals */}
        {tasks.length > 0 && (
          <div className="flex gap-2 text-xs text-slate-400 dark:text-gray-500">
            {totalHrs > 0 && <span>{totalHrs}h</span>}
            {totalCost > 0 && <span className="ml-auto">{fmtCost(totalCost)}</span>}
          </div>
        )}
      </div>

      {/* Cards */}
      <SortableContext items={tasks.map(t => t.id)} strategy={verticalListSortingStrategy}>
        <div className="p-2.5 space-y-2 flex-1">
          {tasks.map(task => <TaskCard key={task.id} task={task} isDragging={false} onEdit={onEdit}/>)}
          {tasks.length === 0 && (
            <div className="border-2 border-dashed border-slate-200 dark:border-surface-600 rounded-xl h-14 flex items-center justify-center">
              <span className="text-xs text-slate-300 dark:text-gray-600">
                {column.id === 'COMPLETADA' ? 'Sin completadas' : 'Arrastra aquí'}
              </span>
            </div>
          )}
        </div>
      </SortableContext>

      {/* Footer add (only on addable columns) */}
      {column.canAdd && (
        <button onClick={() => onAddTask(column.id)}
          className="m-2.5 mt-0 py-2 text-xs text-slate-400 dark:text-gray-500 hover:text-blue-600 dark:hover:text-blue-400 border border-dashed border-slate-200 dark:border-surface-700 hover:border-blue-300 dark:hover:border-blue-500/50 rounded-xl transition cursor-pointer flex items-center justify-center gap-1.5">
          <svg className="w-3 h-3" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2.5}><path strokeLinecap="round" strokeLinejoin="round" d="M12 4v16m8-8H4"/></svg>
          Agregar tarea
        </button>
      )}
    </div>
  );
}

// ── Board ─────────────────────────────────────────────────────────────────────
export default function KanbanBoard({ projectId, tasks, onTasksChange }) {
  const [activeTask, setActiveTask] = useState(null);
  const [modal,      setModal]      = useState(null);
  const sensors = useSensors(useSensor(PointerSensor, { activationConstraint: { distance: 8 } }));

  const tasksByStatus = COLUMNS.reduce((acc, col) => {
    acc[col.id] = tasks.filter(t => t.status === col.id);
    return acc;
  }, {});

  const findColumn = useCallback(id =>
    COLUMNS.find(col => tasksByStatus[col.id]?.some(t => t.id === id))?.id ||
    COLUMNS.find(col => col.id === id)?.id, [tasksByStatus]);

  // Drag — block dragging completed tasks; validate transitions
  const handleDragStart = ({ active }) => {
    const t = tasks.find(t => t.id === active.id);
    if (t?.status === 'COMPLETADA') return; // lock completed
    setActiveTask(t || null);
  };

  const handleDragEnd = async ({ active, over }) => {
    setActiveTask(null);
    if (!over) return;
    const fromStatus = findColumn(active.id);
    const toStatus   = findColumn(over.id);
    if (!fromStatus || !toStatus || fromStatus === toStatus) return;
    // Validate transition
    if (!(ALLOWED_TRANSITIONS[fromStatus] || []).includes(toStatus)) return;
    // Moving to BLOQUEADA requires opening modal
    if (toStatus === 'BLOQUEADA') {
      const t = tasks.find(t => t.id === active.id);
      setModal({ mode:'edit', task: { ...t, status:'BLOQUEADA' } });
      return;
    }
    const updated = tasks.map(t => t.id === active.id ? { ...t, status: toStatus } : t);
    onTasksChange(updated);
    try { await projectsService.updateTaskStatus(active.id, toStatus); }
    catch { onTasksChange(tasks); }
  };

  const handleAdd = status => setModal({ mode:'create', defaultStatus: status });

  const handleCreate = async formData => {
    try {
      const res = await projectsService.createTask(projectId, formData);
      onTasksChange([...tasks, res.task || { id:`tmp-${Date.now()}`, ...formData }]);
    } catch {
      onTasksChange([...tasks, { id:`tmp-${Date.now()}`, ...formData }]);
    }
    setModal(null);
  };

  const handleEditSave = async formData => {
    const originalTask = modal.task;
    const isBeingCompleted = formData.status === 'COMPLETADA' && originalTask.status !== 'COMPLETADA';
    const isQCApproval = originalTask.isQCTask && formData.qcResult;

    let updated = tasks.map(t => t.id === originalTask.id ? { ...t, ...formData } : t);

    // Al completar una tarea normal → auto-crear tarea QC
    if (isBeingCompleted && !originalTask.isQCTask) {
      const qcTask = createQCTask({ ...originalTask, ...formData }, projectId);
      updated = [...updated, qcTask];
    }

    // Si QC aprueba → la tarea QC pasa a COMPLETADA
    if (isQCApproval && formData.qcResult === 'APROBADO') {
      updated = updated.map(t => t.id === originalTask.id ? { ...t, status: 'COMPLETADA', qcResult: 'APROBADO' } : t);
    }

    // Si QC rechaza → tarea original vuelve a EN_PROCESO (no conforme)
    if (isQCApproval && formData.qcResult === 'RECHAZADO') {
      updated = updated.map(t => {
        if (t.id === originalTask.linkedTaskId) return { ...t, status: 'EN_PROCESO', ncr: true };
        if (t.id === originalTask.id) return { ...t, status: 'COMPLETADA', qcResult: 'RECHAZADO' };
        return t;
      });
    }

    onTasksChange(updated);
    try { await projectsService.updateTaskStatus(originalTask.id, formData.status); }
    catch {}
    setModal(null);
  };

  // Board totals
  const totalHrs   = tasks.reduce((s,t)=>s+(t.estimatedHours||0),0);
  const totalCost  = tasks.reduce((s,t)=>s+(calcResourceCost(t.assignee,t.estimatedHours)||0),0);
  const doneCount  = tasks.filter(t=>t.status==='COMPLETADA').length;

  return (
    <>
      {/* Board summary bar */}
      {tasks.length > 0 && (
        <div className="flex flex-wrap gap-4 text-xs text-slate-500 dark:text-gray-400 mb-3 px-1">
          <span><b className="text-slate-800 dark:text-white">{doneCount}/{tasks.length}</b> tareas completadas</span>
          {totalHrs>0 && <span><b className="text-slate-800 dark:text-white">{totalHrs}h</b> estimadas</span>}
          {totalCost>0 && <span><b className="text-slate-800 dark:text-white">{fmtCost(totalCost)}</b> costo planificado</span>}
        </div>
      )}

      <DndContext sensors={sensors} collisionDetection={closestCorners} onDragStart={handleDragStart} onDragEnd={handleDragEnd}>
        <div className="grid grid-cols-5 gap-3 overflow-x-auto pb-2" style={{minWidth:'900px'}}>
          {COLUMNS.map(col => (
            <Column key={col.id} column={col} tasks={tasksByStatus[col.id]||[]}
              onAddTask={handleAdd} onEdit={t=>setModal({mode:'edit',task:t})}/>
          ))}
        </div>
        <DragOverlay>
          {activeTask && <TaskCard task={activeTask} isDragging onEdit={()=>{}}/>}
        </DragOverlay>
      </DndContext>

      {modal && (
        <TaskModal
          task={modal.mode==='edit' ? modal.task : null}
          defaultStatus={modal.defaultStatus || 'PENDIENTE'}
          projectTasks={tasks}
          onSave={modal.mode==='edit' ? handleEditSave : handleCreate}
          onClose={() => setModal(null)}
        />
      )}
    </>
  );
}
