// ─────────────────────────────────────────────────────
// PARTES drawer — submitted parte detail, edit, exports, archivos.
// ─────────────────────────────────────────────────────

const parteDateInput = (s) => {
  if (!s) return '';
  const t = String(s);
  return /^\d{4}-\d{2}-\d{2}/.test(t) ? t.slice(0, 10) : '';
};

const parteInputStyle = {
  width: '100%',
  padding: '6px 8px',
  border: '1px solid var(--line)',
  borderRadius: 4,
  background: 'var(--surface)',
  fontSize: 12.5,
};

const newDespRow = () => ({ h_inicio: '', h_fin: '', ruta: '', kms: '' });
const newInstRow = () => ({ h_inicio: '', h_fin: '', tarea: '' });

const ArchivosMiniPanel = ({ entityType, entityId, onToast }) => {
  const [files, setFiles] = React.useState([]);
  const [loading, setLoading] = React.useState(false);
  const [uploading, setUploading] = React.useState(false);
  const inputRef = React.useRef(null);

  const load = React.useCallback(() => {
    if (!entityId) return;
    setLoading(true);
    API.get('/api/archivos', { entity_type: entityType, entity_id: entityId })
      .then(rows => setFiles(Array.isArray(rows) ? rows : []))
      .catch(e => onToast && onToast(e.message || 'Error al cargar archivos', true))
      .finally(() => setLoading(false));
  }, [entityType, entityId, onToast]);

  React.useEffect(() => { load(); }, [load]);

  const upload = async (ev) => {
    const selected = Array.from(ev.target.files || []);
    if (!selected.length) return;
    const fd = new FormData();
    fd.append('entity_type', entityType);
    fd.append('entity_id', entityId);
    selected.forEach(f => fd.append('files', f));
    setUploading(true);
    try {
      await API.upload('/api/archivos', fd);
      onToast && onToast('Archivo subido ✓');
      load();
    } catch (e) {
      onToast && onToast(e.message || 'Error al subir archivo', true);
    } finally {
      setUploading(false);
      if (inputRef.current) inputRef.current.value = '';
    }
  };

  const del = async (f) => {
    if (!confirm(`¿Eliminar ${f.original_name}?`)) return;
    try {
      await API.del(`/api/archivos/${f.id}`);
      setFiles(rows => rows.filter(x => x.id !== f.id));
      onToast && onToast('Archivo eliminado');
    } catch (e) {
      onToast && onToast(e.message || 'Error al eliminar archivo', true);
    }
  };

  return (
    <div>
      <div style={{display:'flex',justifyContent:'space-between',alignItems:'center',marginBottom:12}}>
        <div className="section-title" style={{margin:0}}>Archivos</div>
        <label className="btn primary" style={{fontSize:12,cursor:'pointer'}}>
          <Icon name="upload" size={12}/> {uploading ? 'Subiendo…' : 'Subir'}
          <input ref={inputRef} type="file" multiple style={{display:'none'}} onChange={upload} disabled={uploading}/>
        </label>
      </div>
      {loading && <div className="muted" style={{fontSize:12,padding:'12px 0'}}>Cargando archivos…</div>}
      {!loading && files.length === 0 && <div className="muted" style={{fontSize:12,padding:'12px 0'}}>Sin archivos adjuntos.</div>}
      <div style={{display:'flex',flexDirection:'column',gap:8}}>
        {files.map(f => (
          <div key={f.id} style={{display:'flex',alignItems:'center',gap:10,padding:10,border:'1px solid var(--line)',borderRadius:6,background:'var(--surface)'}}>
            <Icon name={String(f.mimetype || '').includes('image') ? 'file' : 'file'} size={15}/>
            <div style={{minWidth:0,flex:1}}>
              <div style={{fontSize:12.5,fontWeight:600,overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap'}}>{f.original_name || `Archivo ${f.id}`}</div>
              <div className="muted" style={{fontSize:11}}>{f.mimetype || 'archivo'} · {f.size ? `${Math.round(f.size / 1024)} KB` : '—'}</div>
            </div>
            <button className="btn ghost sm" onClick={() => API.download(`/api/archivos/${f.id}/download`, f.original_name || `archivo_${f.id}`)}>
              <Icon name="download" size={12}/>
            </button>
            <button className="icon-btn" style={{color:'var(--err)'}} onClick={() => del(f)}><Icon name="trash" size={12}/></button>
          </div>
        ))}
      </div>
    </div>
  );
};

const ParteRowsEditor = ({ title, rows, kind, onChange }) => {
  const keys = kind === 'desp'
    ? [['h_inicio', 'Inicio', 'time'], ['h_fin', 'Fin', 'time'], ['ruta', 'Ruta', 'text'], ['kms', 'Km', 'text']]
    : [['h_inicio', 'Inicio', 'time'], ['h_fin', 'Fin', 'time'], ['tarea', 'Tarea', 'text']];
  const blank = kind === 'desp' ? newDespRow : newInstRow;
  const setRow = (idx, key, value) => onChange(rows.map((r, i) => i === idx ? { ...r, [key]: value } : r));
  const removeRow = (idx) => onChange(rows.filter((_, i) => i !== idx));

  return (
    <div>
      <div style={{display:'flex',justifyContent:'space-between',alignItems:'center',marginBottom:10}}>
        <div className="section-title" style={{margin:0}}>{title}</div>
        <button className="btn primary" style={{fontSize:12}} onClick={() => onChange([...(rows || []), blank()])}>
          <Icon name="plus" size={12}/> Añadir
        </button>
      </div>
      {(!rows || rows.length === 0) && <div className="muted" style={{fontSize:12,padding:'12px 0'}}>Sin líneas registradas.</div>}
      <div style={{display:'flex',flexDirection:'column',gap:8}}>
        {(rows || []).map((row, idx) => (
          <div key={idx} style={{display:'grid',gridTemplateColumns:'repeat(auto-fit, minmax(110px, 1fr)) 30px',gap:8,alignItems:'end',padding:10,border:'1px solid var(--line)',borderRadius:6,background:'var(--surface)'}}>
            {keys.map(([key, label, type]) => (
              <div className="field" key={key}>
                <label>{label}</label>
                <input type={type} value={row[key] || ''} onChange={e => setRow(idx, key, e.target.value)} style={parteInputStyle}/>
              </div>
            ))}
            <button className="icon-btn" style={{color:'var(--err)'}} onClick={() => removeRow(idx)}><Icon name="trash" size={12}/></button>
          </div>
        ))}
      </div>
    </div>
  );
};

const PartesDrawer = ({ parteId, onClose, onChanged, onToast }) => {
  const [tab, setTab] = React.useState('detalle');
  const [detail, setDetail] = React.useState(null);
  const [draft, setDraft] = React.useState(null);
  const [saving, setSaving] = React.useState(false);

  const load = React.useCallback(() => {
    if (!parteId) return;
    setDetail(null);
    API.get(`/api/partes/${parteId}`).then(p => {
      const next = {
        ...p,
        fecha: parteDateInput(p.fecha),
        desplazamiento: Array.isArray(p.desplazamiento) ? p.desplazamiento : [],
        instalacion: Array.isArray(p.instalacion) ? p.instalacion : [],
      };
      setDetail(next);
      setDraft(next);
    }).catch(e => onToast && onToast(e.message || 'Error al cargar parte', true));
  }, [parteId, onToast]);

  React.useEffect(() => {
    if (!parteId) { setDetail(null); setDraft(null); return; }
    setTab('detalle');
    load();
  }, [parteId, load]);

  if (!parteId) return null;
  const d = draft || detail;

  const setField = (k, v) => setDraft(prev => ({ ...(prev || {}), [k]: v }));

  const save = async () => {
    if (!draft) return;
    setSaving(true);
    try {
      await API.put(`/api/partes/${parteId}`, {
        fecha: draft.fecha || null,
        cliente: draft.cliente || '',
        num_pedido: draft.num_pedido || '',
        nombre: draft.nombre || '',
        direccion: draft.direccion || '',
        telefono: draft.telefono || '',
        desplazamiento: draft.desplazamiento || [],
        instalacion: draft.instalacion || [],
        total_kms: draft.total_kms || '',
        observaciones: draft.observaciones || '',
      });
      onToast && onToast('Parte guardado ✓');
      load();
      onChanged && onChanged();
    } catch (e) {
      onToast && onToast(e.message || 'Error al guardar parte', true);
    } finally {
      setSaving(false);
    }
  };

  const del = async () => {
    if (!confirm(`¿Eliminar el parte #${parteId}? No se puede deshacer.`)) return;
    try {
      await API.del(`/api/partes/${parteId}`);
      onToast && onToast('Parte eliminado');
      onClose();
      onChanged && onChanged();
    } catch (e) {
      onToast && onToast(e.message || 'Error al eliminar parte', true);
    }
  };

  const exportFile = (format) => {
    const ext = format === 'excel' ? 'xlsx' : 'pdf';
    API.download(`/api/partes/export/${format}?ids=${parteId}`, `parte_${parteId}.${ext}`)
      .catch(e => onToast && onToast(e.message || 'Error al exportar', true));
  };

  return (
    <>
      <div className={`drawer-bg ${parteId ? 'open' : ''}`} onClick={onClose}/>
      <div className={`drawer ${parteId ? 'open' : ''}`}>
        <div className="dr-head">
          <span className="id mono">#{parteId}</span>
          <h2>{d ? (d.cliente || 'Parte de trabajo') : 'Cargando…'}</h2>
          {d && <span className="pill ok"><span className="d"/>Enviado</span>}
          <div className="actions">
            <button className="btn ghost sm tip" data-tip="Guardar" onClick={save} disabled={!d || saving}>
              <Icon name="check" size={13}/>
            </button>
            <button className="btn ghost sm tip" data-tip="Exportar Excel" onClick={() => exportFile('excel')}>
              <Icon name="download" size={13}/>
            </button>
            <button className="btn ghost sm tip" data-tip="Exportar PDF" onClick={() => exportFile('pdf')}>
              <Icon name="print" size={13}/>
            </button>
            <button className="btn ghost sm tip" data-tip="Eliminar" onClick={del} style={{color:'var(--err)'}}>
              <Icon name="trash" size={13}/>
            </button>
            <button className="icon-btn" onClick={onClose}><Icon name="x"/></button>
          </div>
        </div>

        <div className="dr-tabs">
          <button className={tab==='detalle'?'on':''} onClick={()=>setTab('detalle')}>Detalle</button>
          <button className={tab==='desp'?'on':''} onClick={()=>setTab('desp')}>Desplazamiento</button>
          <button className={tab==='inst'?'on':''} onClick={()=>setTab('inst')}>Instalación</button>
          <button className={tab==='archivos'?'on':''} onClick={()=>setTab('archivos')}>Archivos</button>
        </div>

        <div className="dr-body">
          {!d && <div style={{padding:24,textAlign:'center',color:'var(--ink-3)'}}>Cargando…</div>}
          {d && tab === 'detalle' && (
            <div>
              <div className="section-title">Datos generales</div>
              <div className="fields-grid">
                <div className="field"><label>Operario</label><div className="v">{d.operario || '—'}</div></div>
                <div className="field"><label>Enviado</label><div className="v">{d.submitted_at ? new Date(d.submitted_at).toLocaleString('es-ES') : '—'}</div></div>
                <div className="field"><label>Fecha</label><input type="date" value={d.fecha || ''} onChange={e=>setField('fecha', e.target.value)} style={parteInputStyle}/></div>
                <div className="field"><label>Nº pedido</label><input value={d.num_pedido || ''} onChange={e=>setField('num_pedido', e.target.value)} style={parteInputStyle}/></div>
                <div className="field full"><label>Cliente</label><input value={d.cliente || ''} onChange={e=>setField('cliente', e.target.value)} style={parteInputStyle}/></div>
                <div className="field"><label>Contacto</label><input value={d.nombre || ''} onChange={e=>setField('nombre', e.target.value)} style={parteInputStyle}/></div>
                <div className="field"><label>Teléfono</label><input value={d.telefono || ''} onChange={e=>setField('telefono', e.target.value)} style={parteInputStyle}/></div>
                <div className="field full"><label>Dirección</label><input value={d.direccion || ''} onChange={e=>setField('direccion', e.target.value)} style={parteInputStyle}/></div>
                <div className="field"><label>Total KMs</label><input value={d.total_kms || ''} onChange={e=>setField('total_kms', e.target.value)} style={parteInputStyle}/></div>
                <div className="field full"><label>Observaciones</label><textarea value={d.observaciones || ''} onChange={e=>setField('observaciones', e.target.value)} rows="4" style={{...parteInputStyle,resize:'vertical'}}/></div>
              </div>
              <div style={{display:'flex',gap:8,marginTop:14}}>
                <button className="btn primary" onClick={save} disabled={saving}>{saving ? 'Guardando…' : 'Guardar cambios'}</button>
                <button className="btn" onClick={() => exportFile('pdf')}><Icon name="print"/> PDF</button>
              </div>
            </div>
          )}
          {d && tab === 'desp' && (
            <ParteRowsEditor
              title="Desplazamientos"
              kind="desp"
              rows={d.desplazamiento || []}
              onChange={rows => setField('desplazamiento', rows)}
            />
          )}
          {d && tab === 'inst' && (
            <ParteRowsEditor
              title="Instalación"
              kind="inst"
              rows={d.instalacion || []}
              onChange={rows => setField('instalacion', rows)}
            />
          )}
          {d && tab === 'archivos' && (
            <ArchivosPanel entityType="partes" entityId={parteId} title="Archivos del parte" onToast={onToast}/>
          )}
        </div>
      </div>
    </>
  );
};

window.PartesDrawer = PartesDrawer;
