import { useCallback, useEffect, useState } from 'react';
import { useConnection } from '../../context/ConnectionContext';
import { DangerConfirmDialog } from '../FileDialogs';

/**
 * "Device Management" — lists the account's registered devices (or, for
 * owners/admins, everyone's). Each card shows the friendly name, the
 * self-reported hostname, and a collapsible summary of the files it currently
 * holds checked out; expanding reveals each file with a force-check-in button.
 * Deleting a device (X, with a confirm) checks in anything it holds and removes
 * it. Lives in both the Organization and Administration workspaces.
 */
export function DevicesPanel() {
  const { api, account } = useConnection();
  const [devices, setDevices] = useState([]);
  const [admin, setAdmin] = useState(false);
  const [status, setStatus] = useState('loading'); // loading | ready | error
  const [busy, setBusy] = useState(false);
  const [confirm, setConfirm] = useState(null); // device pending deletion
  const [expanded, setExpanded] = useState({}); // deviceKey -> file list open?

  const toggleFiles = (key) =>
    setExpanded((prev) => ({ ...prev, [key]: !prev[key] }));

  const refresh = useCallback(async () => {
    if (!api) return;
    const res = await api.getDevices();
    if (res.ok) {
      setDevices(res.devices ?? []);
      setAdmin(Boolean(res.admin));
      setStatus('ready');
    } else {
      setStatus('error');
    }
  }, [api]);

  useEffect(() => {
    refresh();
    const timer = setInterval(refresh, 20000);
    return () => clearInterval(timer);
  }, [refresh]);

  const checkin = async (device, file) => {
    setBusy(true);
    await api.checkinDeviceFile({ deviceId: device.deviceId, projectId: file.projectId, path: file.path });
    await refresh();
    setBusy(false);
  };

  const remove = async (device) => {
    setConfirm(null);
    setBusy(true);
    await api.removeDevice(device.deviceId);
    await refresh();
    setBusy(false);
  };

  if (!api) {
    return <div className="devices-panel-notice">Connect to a server to manage devices.</div>;
  }
  if (status === 'loading') {
    return <div className="devices-panel-notice">Loading devices…</div>;
  }
  if (status === 'error') {
    return (
      <div className="devices-panel-notice">
        <p>Couldn’t load devices.</p>
        <button type="button" className="workspace-tree-action" onClick={refresh}>
          <img src="assets/refresh.svg" alt="" />
          Retry
        </button>
      </div>
    );
  }

  return (
    <div className="devices-panel">
      {!devices.length && <div className="devices-panel-notice">No devices registered.</div>}
      {devices.map((device) => {
        const deviceKey = `${device.owner ?? ''}:${device.deviceId}`;
        const fileCount = device.files?.length ?? 0;
        const open = Boolean(expanded[deviceKey]);
        return (
        <div key={deviceKey} className="device-card">
          <button
            type="button"
            className="device-card-remove"
            aria-label={`Delete ${device.name}`}
            title="Remove this device"
            onClick={() => setConfirm(device)}
            disabled={busy}
          >
            <img src="assets/close.svg" alt="" />
          </button>
          <div className="device-card-head">
            <div className="device-card-title">
              <span className="device-card-name">{device.name}</span>
              {device.isCurrent && <span className="device-card-badge">this device</span>}
              {admin && device.owner && (
                <span className="device-card-owner">owned by {device.owner}</span>
              )}
            </div>
            <span className="device-card-host">{device.hostname}</span>
          </div>
          <div className="device-card-files">
            {fileCount ? (
              <>
                <button
                  type="button"
                  className="device-files-toggle"
                  aria-expanded={open}
                  onClick={() => toggleFiles(deviceKey)}
                >
                  <img
                    src={open ? 'assets/arrow_down.svg' : 'assets/arrow_right.svg'}
                    alt=""
                    className="tree-toggle-icon"
                  />
                  <span>
                    {fileCount} file{fileCount === 1 ? '' : 's'} checked out
                  </span>
                </button>
                {open && (
                  <div className="device-files-list">
                    {device.files.map((file) => (
                      <div key={`${file.projectId}/${file.path}`} className="device-file-row">
                        <img src="assets/file.svg" alt="" className="device-file-icon" />
                        <span className="device-file-path" title={file.path}>{file.path}</span>
                        <span className="device-file-project">{file.projectName}</span>
                        <button
                          type="button"
                          className="device-file-checkin"
                          aria-label={`Check in ${file.path}`}
                          title="Force check in"
                          onClick={() => checkin(device, file)}
                          disabled={busy}
                        >
                          <img src="assets/submit.svg" alt="" />
                        </button>
                      </div>
                    ))}
                  </div>
                )}
              </>
            ) : (
              <div className="device-card-nofiles">No files checked out</div>
            )}
          </div>
        </div>
        );
      })}

      {confirm && (
        <DangerConfirmDialog
          title="Remove this device?"
          text={
            `“${confirm.name}” will be removed` +
            (confirm.owner && confirm.owner !== account?.username ? ` from ${confirm.owner}` : '') +
            '. ' +
            (confirm.filesCheckedOut
              ? `Its ${confirm.filesCheckedOut} checked-out file${confirm.filesCheckedOut === 1 ? '' : 's'} will be checked in first.`
              : 'It has no files checked out.') +
            (confirm.isCurrent ? ' This is the device you are using — you will be disconnected.' : '')
          }
          confirmLabel="Remove device"
          onCancel={() => setConfirm(null)}
          onConfirm={() => remove(confirm)}
        />
      )}
    </div>
  );
}
