import { h } from 'preact';
import { useState, useEffect } from 'preact/hooks';
import type { PanelACL, Grant, Folder } from './lib/types';

interface Props {
  ifaceId: string;
  ifaceName: string;
  folders: Folder[];
  onClose: () => void;
  onSaved: () => void;
}

// ShareDialog edits a single panel's sharing settings: its folder, public
// visibility, and explicit per-user / per-group grants. Only the owner can
// reach it (the caller is gated upstream in InterfaceList).
export default function ShareDialog({ ifaceId, ifaceName, folders, onClose, onSaved }: Props) {
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [error, setError] = useState('');
  const [owner, setOwner] = useState('');
  const [folder, setFolder] = useState('');
  const [pub, setPub] = useState<'' | 'read' | 'write'>('');
  const [grants, setGrants] = useState<Grant[]>([]);
  const [userGroups, setUserGroups] = useState<string[]>([]);

  // New-grant row state.
  const [newKind, setNewKind] = useState<'user' | 'group'>('user');
  const [newName, setNewName] = useState('');
  const [newPerm, setNewPerm] = useState<'read' | 'write'>('read');

  useEffect(() => {
    Promise.all([
      fetch(`/api/v1/interfaces/${encodeURIComponent(ifaceId)}/acl`).then(r => r.ok ? r.json() : null),
      fetch('/api/v1/usergroups').then(r => r.ok ? r.json() : []),
    ])
      .then(([acl, groups]: [PanelACL | null, string[]]) => {
        if (acl) {
          setOwner(acl.owner || '');
          setFolder(acl.folder || '');
          setPub(acl.public || '');
          setGrants(Array.isArray(acl.grants) ? acl.grants : []);
        }
        setUserGroups(Array.isArray(groups) ? groups : []);
      })
      .catch(() => setError('Failed to load sharing settings.'))
      .finally(() => setLoading(false));
  }, [ifaceId]);

  function addGrant() {
    const name = newName.trim();
    if (!name) return;
    // Replace an existing grant for the same kind+name rather than duplicating.
    const next = grants.filter(g => !(g.kind === newKind && g.name === name));
    next.push({ kind: newKind, name, perm: newPerm });
    setGrants(next);
    setNewName('');
  }

  function removeGrant(idx: number) {
    setGrants(grants.filter((_, i) => i !== idx));
  }

  async function save() {
    setSaving(true);
    setError('');
    try {
      const res = await fetch(`/api/v1/interfaces/${encodeURIComponent(ifaceId)}/acl`, {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ folder, public: pub, grants }),
      });
      if (!res.ok) {
        const msg = await res.json().catch(() => null);
        throw new Error(msg?.error || `Save failed (${res.status})`);
      }
      onSaved();
      onClose();
    } catch (err) {
      setError(err instanceof Error ? err.message : String(err));
      setSaving(false);
    }
  }

  return (
    <div class="wizard-backdrop" onClick={onClose}>
      <div class="wizard" onClick={e => e.stopPropagation()} style="max-width: 560px;">
        <div class="wizard-header">
          <span>Share — {ifaceName || ifaceId}</span>
          <button class="icon-btn" onClick={onClose}>✕</button>
        </div>

        <div class="wizard-body">
          {loading ? (
            <p class="hint">Loading…</p>
          ) : (
            <div>
              {owner && (
                <p class="hint" style="padding: 0 0 0.75rem 0;">Owner: <strong>{owner}</strong></p>
              )}

              <div class="wizard-section-title">Folder</div>
              <div class="wizard-field">
                <select class="prop-select" value={folder} onChange={e => setFolder((e.target as HTMLSelectElement).value)}>
                  <option value="">(root — no folder)</option>
                  {folders.map(f => (
                    <option key={f.id} value={f.id}>{f.name}</option>
                  ))}
                </select>
              </div>

              <div class="wizard-section-title" style="margin-top: 1rem;">Public access</div>
              <div class="wizard-field">
                <select class="prop-select" value={pub} onChange={e => setPub((e.target as HTMLSelectElement).value as any)}>
                  <option value="">Private (only owner & shares)</option>
                  <option value="read">Everyone can view</option>
                  <option value="write">Everyone can edit</option>
                </select>
              </div>

              <div class="wizard-section-title" style="margin-top: 1rem;">Shared with</div>
              {grants.length === 0 ? (
                <p class="hint" style="padding: 0 0 0.5rem 0;">Not shared with anyone yet.</p>
              ) : (
                <ul class="iface-list" style="margin-bottom: 0.5rem;">
                  {grants.map((g, idx) => (
                    <li key={`${g.kind}:${g.name}`} class="iface-item" style="cursor: default;">
                      <span>
                        <span style="font-size: 0.65rem; background: #1e293b; color: #94a3b8; padding: 0 4px; border-radius: 3px; border: 1px solid #334155; margin-right: 6px;">
                          {g.kind}
                        </span>
                        <span style="color: #e2e8f0;">{g.name}</span>
                        <span style="color: #64748b; margin-left: 6px;">({g.perm})</span>
                      </span>
                      <button class="icon-btn iface-delete" title="Remove" onClick={() => removeGrant(idx)}>✕</button>
                    </li>
                  ))}
                </ul>
              )}

              <div class="wizard-field wizard-field-row" style="gap: 0.5rem; align-items: center;">
                <select class="prop-select" style="flex: 0 0 80px;" value={newKind} onChange={e => { setNewKind((e.target as HTMLSelectElement).value as any); setNewName(''); }}>
                  <option value="user">User</option>
                  <option value="group">Group</option>
                </select>
                {newKind === 'group' ? (
                  <select class="prop-select" style="flex: 1;" value={newName} onChange={e => setNewName((e.target as HTMLSelectElement).value)}>
                    <option value="">Select group…</option>
                    {userGroups.map(g => <option key={g} value={g}>{g}</option>)}
                  </select>
                ) : (
                  <input
                    class="prop-input"
                    style="flex: 1;"
                    placeholder="username"
                    value={newName}
                    onInput={e => setNewName((e.target as HTMLInputElement).value)}
                    onKeyDown={e => e.key === 'Enter' && addGrant()}
                  />
                )}
                <select class="prop-select" style="flex: 0 0 80px;" value={newPerm} onChange={e => setNewPerm((e.target as HTMLSelectElement).value as any)}>
                  <option value="read">read</option>
                  <option value="write">write</option>
                </select>
                <button class="panel-btn" onClick={addGrant} disabled={!newName.trim()}>Add</button>
              </div>

              {error && <p class="wizard-error" style="margin-top: 0.75rem;">{error}</p>}
            </div>
          )}
        </div>

        <div class="wizard-footer">
          <button class="toolbar-btn" onClick={onClose}>Cancel</button>
          <button class="toolbar-btn toolbar-btn-primary" onClick={save} disabled={saving || loading}>
            {saving ? 'Saving…' : 'Save'}
          </button>
        </div>
      </div>
    </div>
  );
}
