// Global Worker VPS Manager

const statusBadge = (status) => {
  const map = {
    unprovisioned: { label: 'Not Set Up',   bg: 'var(--bg-hover)',    color: 'var(--fg-3)' },
    provisioned:   { label: '✅ Ready',       bg: 'var(--green-50)',   color: 'var(--green-deep)' },
    failed:        { label: '❌ Failed',       bg: '#fff0f0',           color: '#e74c3c' },
  };
  const s = map[status] || map.unprovisioned;
  return (
    <span style={{ fontSize: 10, fontWeight: 700, padding: '2px 8px', borderRadius: 5,
      background: s.bg, color: s.color, border: '1px solid var(--border-soft)', textTransform: 'uppercase', flexShrink: 0 }}>
      {s.label}
    </span>
  );
};

const VpsForm = ({ initial, onSave, onCancel, saveLabel = 'Add VPS' }) => {
  const blank = { label: '', ip: '', ssh_pass: '', port: '3100' };
  const [fields, setFields] = React.useState(initial || blank);
  const [showPass, setShowPass] = React.useState(false);
  const up = k => v => setFields(f => ({ ...f, [k]: v }));
  const isValid = fields.ip.trim() && fields.ssh_pass.trim();

  React.useEffect(() => { setFields(initial || blank); }, [initial?.ip]);

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
      <Input label="Label" placeholder="e.g. Worker-01" value={fields.label} onChange={up('label')} />
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 100px', gap: 10 }}>
        <Input label="IP Address" placeholder="45.77.123.10" value={fields.ip} onChange={up('ip')} mono />
        <Input label="Port" placeholder="3100" value={fields.port} onChange={up('port')} mono />
      </div>
      <Input label="SSH Password" type={showPass ? 'text' : 'password'} placeholder="root password"
        value={fields.ssh_pass} onChange={up('ssh_pass')}
        suffix={
          <button onClick={() => setShowPass(s => !s)} style={{ background: 'none', border: 'none', cursor: 'pointer', padding: 0, display: 'flex', alignItems: 'center' }}>
            <Icon name={showPass ? 'eye-off' : 'eye'} size={13} color="var(--fg-3)" />
          </button>
        } />
      <div style={{ display: 'flex', gap: 8, justifyContent: 'flex-end' }}>
        {onCancel && <Button variant="ghost" onClick={onCancel}>Cancel</Button>}
        <Button variant="primary" icon="save" onClick={() => isValid && onSave(fields)} disabled={!isValid}>
          {saveLabel}
        </Button>
      </div>
    </div>
  );
};

// Draggable floating log panel — multiple can be open simultaneously
const VpsLogPanel = ({ vpsId, vpsLabel, isMaster, profileId, profileName, initialPos, onClose, onFocus, zIndex }) => {
  const [logs, setLogs] = React.useState([]);
  const [loading, setLoading] = React.useState(false);
  const [autoRefresh, setAutoRefresh] = React.useState(false);
  const [minimized, setMinimized] = React.useState(false);
  const [pos, setPos] = React.useState(initialPos || { x: 80, y: 80 });
  const [filter, setFilter] = React.useState('ALL');
  const [userScrolled, setUserScrolled] = React.useState(false);
  const size = { w: 620, h: 420 };
  const bottomRef = React.useRef(null);
  const scrollRef = React.useRef(null);
  const intervalRef = React.useRef(null);
  const userScrolledRef = React.useRef(false);

  const scrollToBottom = () => {
    if (!userScrolledRef.current && scrollRef.current) {
      scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
    }
  };

  const handleScroll = () => {
    if (!scrollRef.current) return;
    const { scrollTop, scrollHeight, clientHeight } = scrollRef.current;
    const atBottom = scrollHeight - scrollTop - clientHeight < 30;
    userScrolledRef.current = !atBottom;
    setUserScrolled(!atBottom);
  };

  const fetchLogs = async () => {
    setLoading(true);
    try {
      const token = localStorage.getItem('accessToken');
      const url = profileId ? `/api/booking/${profileId}/logs?lines=300` : isMaster ? '/api/master/logs?lines=300' : `/api/worker-vps/${vpsId}/logs?lines=300`;
      const r = await fetch(url, { headers: token ? { Authorization: `Bearer ${token}` } : {} });
      const data = await r.json();
      if (data.ok) {
        const all = [...(data.logs || []), ...(data.errors || [])];
        setLogs(all);
        setTimeout(scrollToBottom, 50);
      }
    } catch (e) { console.error(e); }
    finally { setLoading(false); }
  };

  const clearLogs = async () => {
    if (!confirm('Clear all log files on this server?')) return;
    const token = localStorage.getItem('accessToken');
    const url = profileId ? `/api/booking/${profileId}/logs/clear` : isMaster ? '/api/master/logs/clear' : `/api/worker-vps/${vpsId}/logs/clear`;
    await fetch(url, { method: 'POST', headers: token ? { Authorization: `Bearer ${token}` } : {} });
    setLogs([]);
  };

  React.useEffect(() => { fetchLogs(); return () => clearInterval(intervalRef.current); }, [vpsId]);
  React.useEffect(() => {
    clearInterval(intervalRef.current);
    if (autoRefresh) intervalRef.current = setInterval(fetchLogs, 3000);
    return () => clearInterval(intervalRef.current);
  }, [autoRefresh, vpsId]);

  // Drag logic
  const onDragStart = (e) => {
    onFocus();
    const startX = e.clientX - pos.x, startY = e.clientY - pos.y;
    const onMove = (e) => setPos({ x: e.clientX - startX, y: e.clientY - startY });
    const onUp = () => { document.removeEventListener('mousemove', onMove); document.removeEventListener('mouseup', onUp); };
    document.addEventListener('mousemove', onMove);
    document.addEventListener('mouseup', onUp);
  };

  const colorLine = (line) => {
    if (line.includes('[ERR]') || line.includes('ERROR')) return '#ff6b6b';
    if (line.includes('[WARN]') || line.includes('WARN')) return '#ffd93d';
    if (line.includes('✅') || line.includes('SUCCESS')) return '#6bcb77';
    if (line.includes('[INFO]')) return '#a8dadc';
    return '#cdd6f4';
  };

  const accentColor = profileId ? '#a6e3a1' : isMaster ? '#cba6f7' : '#89dceb';
  const title = profileId ? `📋 ${profileName || profileId.slice(0, 8)}` : isMaster ? '🖥 Master' : `⚙️ ${vpsLabel}`;

  return (
    <div onMouseDown={onFocus} style={{
      position: 'fixed', left: pos.x, top: pos.y, width: size.w,
      zIndex, display: 'flex', flexDirection: 'column',
      background: '#1e1e2e', borderRadius: 12, overflow: 'hidden',
      boxShadow: '0 8px 40px rgba(0,0,0,0.6)', border: `1.5px solid ${accentColor}44`,
      resize: minimized ? 'none' : 'both',
      minWidth: 340, minHeight: minimized ? 0 : 200,
      height: minimized ? 'auto' : size.h,
    }}>
      {/* Title bar — drag handle */}
      <div onMouseDown={onDragStart} style={{
        display: 'flex', alignItems: 'center', gap: 8, padding: '8px 12px',
        background: '#181825', borderBottom: minimized ? 'none' : '1px solid #313244',
        cursor: 'grab', userSelect: 'none', flexShrink: 0,
      }}>
        <Icon name="terminal" size={12} color={accentColor} />
        <span style={{ fontFamily: 'var(--font-mono)', fontSize: 12, fontWeight: 700, color: '#cdd6f4', flex: 1 }}>{title}</span>
        {/* Live badge */}
        {autoRefresh && !minimized && (
          <span style={{ fontSize: 9, fontWeight: 700, padding: '1px 6px', borderRadius: 4, background: 'rgba(166,227,161,0.15)', color: '#a6e3a1', border: '1px solid #a6e3a133' }}>● LIVE</span>
        )}
        <button onClick={fetchLogs} disabled={loading} title="Refresh" style={{ background: 'none', border: 'none', cursor: 'pointer', padding: 2, display: 'flex' }}>
          <Icon name="refresh-cw" size={11} className={loading ? 'icon-rotating' : ''} color="#89b4fa" />
        </button>
        <button onClick={() => setAutoRefresh(a => !a)} title={autoRefresh ? 'Stop live' : 'Start live'} style={{ background: 'none', border: 'none', cursor: 'pointer', padding: 2, display: 'flex' }}>
          <Icon name="activity" size={11} color={autoRefresh ? '#a6e3a1' : '#585b70'} />
        </button>
        <button onClick={clearLogs} title="Clear logs" style={{ background: 'none', border: 'none', cursor: 'pointer', padding: 2, display: 'flex' }}>
          <Icon name="trash-2" size={11} color="#f38ba8" />
        </button>
        <button onClick={() => setMinimized(m => !m)} title={minimized ? 'Expand' : 'Minimize'} style={{ background: 'none', border: 'none', cursor: 'pointer', padding: 2, display: 'flex' }}>
          <Icon name={minimized ? 'maximize-2' : 'minus'} size={11} color="#585b70" />
        </button>
        <button onClick={onClose} title="Close" style={{ background: 'none', border: 'none', cursor: 'pointer', padding: 2, display: 'flex' }}>
          <Icon name="x" size={11} color="#f38ba8" />
        </button>
      </div>

      {!minimized && (
        <>
          {/* Filter buttons */}
          <div style={{ display: 'flex', gap: 4, padding: '4px 10px', background: '#181825', borderBottom: '1px solid #313244', flexShrink: 0 }}>
            {['ALL', 'ERR', 'WARN', 'INFO'].map(f => (
              <button key={f} onClick={() => setFilter(f)} style={{
                fontSize: 9, fontWeight: 700, padding: '2px 8px', borderRadius: 4, cursor: 'pointer', border: 'none',
                background: filter === f ? (f === 'ERR' ? '#f38ba8' : f === 'WARN' ? '#f9e2af' : f === 'INFO' ? '#89b4fa' : '#585b70') : '#313244',
                color: filter === f ? '#1e1e2e' : '#6c7086',
              }}>{f}</button>
            ))}
            {userScrolled && (
              <button onClick={() => { userScrolledRef.current = false; setUserScrolled(false); scrollRef.current && (scrollRef.current.scrollTop = scrollRef.current.scrollHeight); }}
                style={{ marginLeft: 'auto', fontSize: 9, padding: '2px 8px', borderRadius: 4, cursor: 'pointer', border: '1px solid #585b70', background: 'transparent', color: '#f9e2af' }}>
                ⏸ Resume ↓
              </button>
            )}
          </div>
          <div ref={scrollRef} onScroll={handleScroll} style={{ flex: 1, overflowY: 'auto', padding: '8px 12px', fontFamily: 'var(--font-mono)', fontSize: 10.5, lineHeight: 1.65 }}>
            {(() => {
              const filteredLogs = logs
                .filter(line => filter === 'ALL' || line.toUpperCase().includes(filter))
                .slice(-200);
              if (filteredLogs.length === 0 && !loading) return <div style={{ color: '#45475a', textAlign: 'center', marginTop: 30 }}>No logs yet</div>;
              return filteredLogs.map((line, i) => (
                <div key={i} style={{ color: colorLine(line), whiteSpace: 'pre-wrap', wordBreak: 'break-all' }}>{line}</div>
              ));
            })()}
          </div>
          <div style={{ padding: '4px 12px', background: '#11111b', fontSize: 9.5, color: '#45475a', fontFamily: 'var(--font-mono)', flexShrink: 0 }}>
            {logs.filter(line => filter === 'ALL' || line.toUpperCase().includes(filter)).length} / {logs.length} lines · drag to move · resize from corner
          </div>
        </>
      )}
    </div>
  );
};

// Container that manages multiple open log panels
const VpsLogManager = ({ panels, onClose, onFocus, zOrders }) => (
  <>
    {panels.map(p => (
      <VpsLogPanel
        key={p.key}
        vpsId={p.vpsId}
        vpsLabel={p.label}
        isMaster={p.isMaster}
        profileId={p.profileId}
        profileName={p.label}
        initialPos={p.pos}
        zIndex={300 + (zOrders.indexOf(p.key))}
        onClose={() => onClose(p.key)}
        onFocus={() => onFocus(p.key)}
      />
    ))}
  </>
);

const VpsManagerPanel = ({ vpsList, onAdd, onUpdate, onDelete, profiles, onOpenLog }) => {
  const [adding, setAdding] = React.useState(false);
  const [editId, setEditId] = React.useState(null);

  const openLog = (key, vpsId, label, isMaster) => onOpenLog?.(key, vpsId, label, isMaster);

  const assignedProfileName = (vps) => {
    if (!vps.assigned_profile) return null;
    const p = profiles?.find(p => p.id === vps.assigned_profile);
    return p ? p.name : vps.assigned_profile.slice(0, 8);
  };

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 20 }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
        <Button variant="ghost" icon="terminal" onClick={() => openLog('master', null, 'Master', true)}>
          Master Logs
        </Button>
        {!adding && (
          <Button variant="primary" icon="plus" onClick={() => { setAdding(true); setEditId(null); }}>
            Add VPS
          </Button>
        )}
      </div>

      {adding && (
        <div style={{ background: '#fff', border: '1.5px solid var(--blue,#2563eb)', borderRadius: 14, padding: 20 }}>
          <div style={{ fontSize: 11, fontWeight: 700, letterSpacing: '0.08em', textTransform: 'uppercase',
            color: 'var(--blue,#2563eb)', marginBottom: 14 }}>New Worker VPS</div>
          <VpsForm
            saveLabel="Add VPS"
            onSave={(f) => { onAdd?.(f); setAdding(false); }}
            onCancel={() => setAdding(false)}
          />
        </div>
      )}

      <div style={{ background: '#fff', border: '1px solid var(--border)', borderRadius: 14, padding: 20 }}>
        <div style={{ display: 'flex', alignItems: 'center', marginBottom: 14 }}>
          <div style={{ fontSize: 11, fontWeight: 700, letterSpacing: '0.08em', textTransform: 'uppercase', color: 'var(--fg-label)' }}>VPS Pool</div>
          <span style={{ marginLeft: 8, fontSize: 11, color: 'var(--fg-4)' }}>{(vpsList || []).length} servers</span>
        </div>

        {(vpsList || []).length === 0 ? (
          <EmptyState icon="server" title="No VPS added yet" subtitle="Add a worker VPS above to build the pool." />
        ) : (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
            {(vpsList || []).map((vps) => {
              const isEditing = editId === vps.id;
              const assignedName = assignedProfileName(vps);
              return (
                <div key={vps.id} style={{
                  border: isEditing ? '1.5px solid var(--blue,#2563eb)' : '1px solid var(--border)',
                  borderRadius: 10, overflow: 'hidden',
                }}>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '10px 14px',
                    background: isEditing ? '#EFF6FF' : 'var(--bg-app)' }}>
                    <Icon name="server" size={13} color="var(--fg-3)" />
                    {statusBadge(vps.status)}
                    <div style={{ flex: 1, minWidth: 0 }}>
                      <div style={{ fontWeight: 700, fontSize: 13, color: 'var(--fg-1)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                        {vps.label || vps.ip}
                      </div>
                      <div style={{ fontFamily: 'var(--font-mono)', fontSize: 11, color: 'var(--fg-3)' }}>
                        {vps.ip}:{vps.port || 3100}
                      </div>
                    </div>
                    {assignedName ? (
                      <span style={{ display: 'inline-flex', alignItems: 'center', gap: 4, fontSize: 10, fontWeight: 700,
                        padding: '2px 8px', borderRadius: 4, background: 'var(--teal-50)', color: 'var(--teal-ink)',
                        border: '1px solid var(--teal-100,#99F6E4)', whiteSpace: 'nowrap', flexShrink: 0 }}>
                        <Icon name="user" size={9} />{assignedName}
                      </span>
                    ) : (
                      <span style={{ fontSize: 10, color: 'var(--fg-4)', fontWeight: 500, flexShrink: 0 }}>free</span>
                    )}
                    <div style={{ display: 'flex', gap: 4, flexShrink: 0 }}>
                      <IconButton icon="terminal" onClick={() => openLog(vps.id, vps.id, vps.label || vps.ip, false)} title="View Logs" />
                      <IconButton icon="pencil" onClick={() => setEditId(isEditing ? null : vps.id)} title="Edit" />
                      <IconButton icon="trash-2" variant="pink" onClick={() => onDelete?.(vps.id)} title="Delete" />
                    </div>
                  </div>

                  {isEditing && (
                    <div style={{ padding: 16, borderTop: '1px solid var(--border-soft)', background: '#fff' }}>
                      <VpsForm
                        initial={{ label: vps.label, ip: vps.ip, ssh_pass: '', port: String(vps.port || 3100) }}
                        saveLabel="Save Changes"
                        onSave={(f) => { onUpdate?.(vps.id, f); setEditId(null); }}
                        onCancel={() => setEditId(null)}
                      />
                    </div>
                  )}
                </div>
              );
            })}
          </div>
        )}
      </div>
    </div>
  );
};

// Picker used inside ProfileModal
const VpsPicker = ({ vpsList, profileId, currentWorkerIp, currentProvisioned, onAssigned }) => {
  const [selected, setSelected] = React.useState('');
  const [provisioning, setProvisioning] = React.useState(false);
  const [msg, setMsg] = React.useState('');

  const handleAssign = async () => {
    if (!selected) return;
    setProvisioning(true);
    const selectedVps = vpsList.find(v => v.id === selected);
    const isAlreadyProvisioned = selectedVps?.status === 'provisioned';
    setMsg(isAlreadyProvisioned ? 'Assigning… ~15s' : 'Provisioning… ~2-3 min');
    try {
      const token = localStorage.getItem('accessToken');
      const resp = await fetch(`/api/profiles/${profileId}/assign-worker-vps`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', ...(token ? { Authorization: `Bearer ${token}` } : {}) },
        body: JSON.stringify({ vpsId: selected }),
      });
      const data = await resp.json();
      if (data.ok) {
        const vps = selectedVps;
        setMsg(isAlreadyProvisioned ? `✅ Assigned ${vps?.ip}. Ready in ~15s.` : `✅ Provisioning started for ${vps?.ip}. Ready in ~2 min.`);
        onAssigned?.({ worker_ip: vps?.ip, worker_provisioned: isAlreadyProvisioned ? 1 : 0 });
      } else {
        setMsg(`❌ ${data.error}`);
      }
    } catch (e) {
      setMsg(`❌ ${e.message}`);
    } finally {
      setProvisioning(false);
    }
  };

  const handleUnassign = async () => {
    if (!confirm('Unassign worker VPS from this profile?')) return;
    const token = localStorage.getItem('accessToken');
    await fetch(`/api/profiles/${profileId}/assign-worker`, {
      method: 'DELETE',
      headers: token ? { Authorization: `Bearer ${token}` } : {},
    });
    onAssigned?.({ worker_ip: '', worker_provisioned: 0 });
    setMsg('');
  };

  const freeVps = (vpsList || []).filter(v => !v.assigned_profile || v.assigned_profile === profileId);

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 8, padding: '12px 14px',
      borderRadius: 10, border: '1.5px solid var(--border)', background: '#f8faff' }}>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
        <div style={{ fontSize: 11, fontWeight: 700, letterSpacing: '0.08em', textTransform: 'uppercase', color: 'var(--fg-label)' }}>
          Worker VPS
        </div>
        {currentWorkerIp && currentProvisioned === 1 && (
          <span style={{ fontSize: 11, fontWeight: 700, color: 'var(--green)', background: 'var(--green-50)', borderRadius: 6, padding: '2px 8px' }}>
            ✅ {currentWorkerIp}
          </span>
        )}
        {currentWorkerIp && currentProvisioned !== 1 && (
          <span style={{ fontSize: 11, fontWeight: 700, color: '#e67e22', background: '#fff8ee', borderRadius: 6, padding: '2px 8px' }}>
            ⏳ Provisioning…
          </span>
        )}
      </div>

      {!currentWorkerIp ? (
        freeVps.length === 0 ? (
          <div style={{ fontSize: 12, color: 'var(--fg-3)', textAlign: 'center', padding: '8px 0' }}>
            No free VPS in pool. Add one in <b>Worker VPS</b> page.
          </div>
        ) : (
          <>
            <select value={selected} onChange={e => setSelected(e.target.value)}
              style={{ padding: '8px 10px', borderRadius: 8, border: '1.5px solid var(--border)', fontSize: 13, background: '#fff' }}>
              <option value="">Select a VPS…</option>
              {freeVps.map(v => (
                <option key={v.id} value={v.id}>{v.label || v.ip} — {v.ip}:{v.port || 3100}</option>
              ))}
            </select>
            <button onClick={handleAssign} disabled={!selected || provisioning}
              style={{ padding: '9px 0', borderRadius: 8, fontWeight: 700, fontSize: 12,
                cursor: (!selected || provisioning) ? 'not-allowed' : 'pointer',
                background: (!selected || provisioning) ? '#ccc' : 'var(--blue,#2563eb)', color: '#fff', border: 'none' }}>
              {provisioning ? 'Provisioning…' : '🚀 Assign & Provision'}
            </button>
          </>
        )
      ) : (
        <button onClick={handleUnassign}
          style={{ padding: '7px 0', borderRadius: 8, fontWeight: 700, fontSize: 12,
            cursor: 'pointer', background: '#fff', color: '#e74c3c', border: '1.5px solid #e74c3c' }}>
          Unassign Worker
        </button>
      )}

      {msg && <div style={{ fontSize: 11, color: msg.startsWith('❌') ? '#e74c3c' : '#27ae60', marginTop: 2 }}>{msg}</div>}
    </div>
  );
};

Object.assign(window, { VpsManagerPanel, VpsPicker });
