import { FormEvent, useCallback, useEffect, useState } from 'react';
import Layout from '../../components/Layout';
import { api } from '../../lib/api';
import { useRequireAuth } from '../../lib/auth-context';

interface DeviceRow {
  id: string;
  name: string;
  serialNumber: string | null;
  mqttUsername: string | null;
  isActive: boolean;
  lastSeenAt: string | null;
}

export default function DevicesPage() {
  const { user, activeOrg, loading } = useRequireAuth();
  const orgId = activeOrg?.org.id ?? null;
  const isAdmin = activeOrg?.role === 'ORG_ADMIN';

  const [devices, setDevices] = useState<DeviceRow[]>([]);
  const [form, setForm] = useState({ name: '', mqttUsername: '', serialNumber: '' });
  const [notice, setNotice] = useState<string | null>(null);
  const [error, setError] = useState<string | null>(null);

  const reload = useCallback(() => {
    if (!orgId) {
      return;
    }
    api
      .get<DeviceRow[]>(`/api/orgs/${orgId}/devices`)
      .then((rows) => {
        setDevices(rows);
        setError(null);
      })
      .catch((err) => setError(err.message));
  }, [orgId]);

  useEffect(reload, [reload]);

  const addDevice = async (e: FormEvent) => {
    e.preventDefault();
    try {
      const created = await api.post<DeviceRow & { provisioning: { pointsTopic?: string; note: string } }>(
        `/api/orgs/${orgId}/devices`,
        {
          name: form.name,
          mqttUsername: form.mqttUsername || undefined,
          serialNumber: form.serialNumber || undefined,
        },
      );
      setNotice(
        created.provisioning.pointsTopic
          ? `Device created. It should publish points to ${created.provisioning.pointsTopic}`
          : created.provisioning.note,
      );
      setForm({ name: '', mqttUsername: '', serialNumber: '' });
      reload();
    } catch (err: any) {
      setError(err.message);
    }
  };

  const toggleActive = async (device: DeviceRow) => {
    try {
      await api.patch(`/api/orgs/${orgId}/devices/${device.id}`, { isActive: !device.isActive });
      reload();
    } catch (err: any) {
      setError(err.message);
    }
  };

  const remove = async (deviceId: string) => {
    try {
      await api.delete(`/api/orgs/${orgId}/devices/${deviceId}`);
      reload();
    } catch (err: any) {
      setError(err.message);
    }
  };

  if (loading || !user) {
    return null;
  }

  return (
    <Layout title="Devices">
      <h1>Devices</h1>
      <p style={{ color: '#666' }}>
        Field devices publish to <code>devices/&lt;mqtt username&gt;/points</code>. Broker credentials are provisioned
        separately for now.
      </p>
      {error && <p style={{ color: '#c62828' }}>{error}</p>}
      {notice && <p style={{ color: '#388e3c' }}>{notice}</p>}

      {isAdmin && (
        <form onSubmit={addDevice} style={{ display: 'flex', gap: '0.5rem', marginBottom: '1.5rem', flexWrap: 'wrap' }}>
          <input
            placeholder="name"
            value={form.name}
            onChange={(e) => setForm((f) => ({ ...f, name: e.target.value }))}
            required
            style={{ padding: '0.4rem' }}
          />
          <input
            placeholder="serial number"
            value={form.serialNumber}
            onChange={(e) => setForm((f) => ({ ...f, serialNumber: e.target.value }))}
            style={{ padding: '0.4rem' }}
          />
          <input
            placeholder="mqtt username (only if it connects itself)"
            value={form.mqttUsername}
            onChange={(e) => setForm((f) => ({ ...f, mqttUsername: e.target.value }))}
            style={{ padding: '0.4rem' }}
          />
          <button type="submit">Add device</button>
        </form>
      )}

      <table style={{ width: '100%', borderCollapse: 'collapse' }}>
        <thead>
          <tr style={{ textAlign: 'left', borderBottom: '2px solid #ddd' }}>
            <th style={{ padding: '0.5rem' }}>Name</th>
            <th>MQTT username</th>
            <th>Serial</th>
            <th>Status</th>
            <th>Last seen</th>
            {isAdmin && <th />}
          </tr>
        </thead>
        <tbody>
          {devices.map((d) => (
            <tr key={d.id} style={{ borderBottom: '1px solid #eee' }}>
              <td style={{ padding: '0.5rem' }}>{d.name}</td>
              <td>{d.mqttUsername ? <code>{d.mqttUsername}</code> : '—'}</td>
              <td>{d.serialNumber ?? '—'}</td>
              <td style={{ color: d.isActive ? '#388e3c' : '#9e9e9e' }}>{d.isActive ? 'active' : 'disabled'}</td>
              <td>{d.lastSeenAt ? new Date(d.lastSeenAt).toLocaleString() : 'never'}</td>
              {isAdmin && (
                <td style={{ textAlign: 'right', whiteSpace: 'nowrap' }}>
                  <button onClick={() => toggleActive(d)}>{d.isActive ? 'Disable' : 'Enable'}</button>{' '}
                  <button onClick={() => remove(d.id)}>Delete</button>
                </td>
              )}
            </tr>
          ))}
        </tbody>
      </table>
    </Layout>
  );
}
