// Add/Edit modal for domains and servers.

const DOMAIN_DEFAULTS = { name: '', registrar: 'GoDaddy', start: '', expiry: '', autoRenew: false, billedCost: '', purchasedCost: '', clientId: '', serverId: '', role: null, groupId: '', healthCheckEnabled: false, healthCheckInterval: 30, healthCheckUrl: '', pm2AppName: '', expiryNotifyDays: '30,15,7,3,2,1' };
const SERVER_DEFAULTS = { label: '', provider: 'Hetzner', ip: '', panelDomain: '', os: 'Ubuntu 24.04', cpu: 2, ram: 4, disk: 80, region: '', start: '', expiry: '', autoRenew: false, billedCost: '', purchasedCost: '', type: 'individual', clientId: '', healthCheckEnabled: false, healthCheckInterval: 30, healthCheckUrl: '', sshConfigured: false, sshKeyFile: '', sshUser: 'root', expiryNotifyDays: '30,15,7,3,2,1' };

const CHECK_INTERVALS = [
  { value: 5,  label: '5 minutes' },
  { value: 15, label: '15 minutes' },
  { value: 30, label: '30 minutes' },
  { value: 60, label: '1 hour' },
];

const HealthMonitorSection = ({ form, set, kind }) => (
  <div style={{ marginTop: 20, borderTop: '1px solid var(--border)', paddingTop: 16 }}>
    <div style={{ fontSize: 11, fontWeight: 600, letterSpacing: '0.06em', color: 'var(--text-muted)', textTransform: 'uppercase', marginBottom: 12 }}>
      Health Monitoring
    </div>
    <div className="field check" style={{ marginBottom: 12 }}>
      <input
        type="checkbox"
        id={`hc-enabled-${kind}`}
        checked={!!form.healthCheckEnabled}
        onChange={(e) => set('healthCheckEnabled', e.target.checked)}
      />
      <label htmlFor={`hc-enabled-${kind}`}>Enable health check</label>
    </div>
    {form.healthCheckEnabled && (
      <>
        <div className="field-grid">
          <div className="field">
            <label>Check interval</label>
            <select
              value={form.healthCheckInterval || 30}
              onChange={(e) => set('healthCheckInterval', Number(e.target.value))}
            >
              {CHECK_INTERVALS.map(opt => (
                <option key={opt.value} value={opt.value}>{opt.label}</option>
              ))}
            </select>
          </div>
          <div className="field">
            <label>Custom check URL <span style={{ color: 'var(--text-muted)', fontWeight: 400 }}>(optional)</span></label>
            <input
              value={form.healthCheckUrl || ''}
              onChange={(e) => set('healthCheckUrl', e.target.value)}
              placeholder={kind === 'domain' ? 'auto: https://<domain>' : 'auto: http://<ip>'}
            />
            <span className="hint">
              {kind === 'domain'
                ? 'Leave blank to auto-check https://<domain>. Any HTTP response = up; timeout = down.'
                : 'Leave blank to check panel domain or server IP. Add a /health path if available.'}
            </span>
          </div>
        </div>
        <div className="field">
          <label>Expiry alert days <span style={{ color: 'var(--text-muted)', fontWeight: 400 }}>(comma-separated)</span></label>
          <input
            value={form.expiryNotifyDays || '30,15,7,3,2,1'}
            onChange={(e) => set('expiryNotifyDays', e.target.value)}
            placeholder="30,15,7,3,2,1"
          />
          <span className="hint">Days before expiry to send Telegram alerts. Last 3 days are always notified regardless of this setting.</span>
        </div>
      </>
    )}
  </div>
);
const SshConfigSection = ({ form, set }) => (
  <div style={{ marginTop: 20, borderTop: '1px solid var(--border)', paddingTop: 16 }}>
    <div style={{ fontSize: 11, fontWeight: 600, letterSpacing: '0.06em', color: 'var(--text-muted)', textTransform: 'uppercase', marginBottom: 12 }}>
      SSH / PM2 Access
    </div>
    <div className="field check" style={{ marginBottom: 12 }}>
      <input
        type="checkbox"
        id="ssh-configured"
        checked={!!form.sshConfigured}
        onChange={(e) => set('sshConfigured', e.target.checked)}
      />
      <label htmlFor="ssh-configured">SSH configured (enables Telegram bot PM2 control)</label>
    </div>
    {form.sshConfigured && (
      <div className="field-grid">
        <div className="field">
          <label>SSH key file path</label>
          <input
            value={form.sshKeyFile || ''}
            onChange={(e) => set('sshKeyFile', e.target.value)}
            placeholder="~/.ssh/bot_key_148.230.67.218_hostnew"
          />
          <span className="hint">Full path to the private key used by the bot. Run <code>scripts/setup-ssh-server.sh</code> to generate.</span>
        </div>
        <div className="field">
          <label>SSH user</label>
          <input
            value={form.sshUser || 'root'}
            onChange={(e) => set('sshUser', e.target.value)}
            placeholder="root"
          />
        </div>
      </div>
    )}
  </div>
);

const CLIENT_DEFAULTS = { name: '', contact: '', phone: '', tag: '', email: '' };

const REGISTRARS = ['GoDaddy', 'Namecheap', 'Cloudflare', 'Porkbun', 'BigRock', 'Google Domains'];
const PROVIDERS = ['Hetzner', 'DigitalOcean', 'AWS EC2', 'AWS Lightsail', 'Contabo', 'Vultr', 'Linode', 'Hostinger', 'Other'];
const OSES = ['Ubuntu 24.04', 'Ubuntu 22.04', 'Debian 12', 'Amazon Linux', 'AlmaLinux 9', 'Rocky Linux 9', 'Windows Server 2022'];

// Validation helpers
const validateEmail = (email) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
const validatePhone = (phone) => /^[\d\s\-\+\(\)]{6,}$/.test(phone);
const validateUrl = (url) => {
  try { new URL(url); return true; } catch { return false; }
};
const validateRequired = (value) => value && String(value).trim().length > 0;
const validateDate = (date) => /^\d{4}-\d{2}-\d{2}$/.test(date);
const validateNumber = (num) => !isNaN(num) && num >= 0;

const getValidationErrors = (form, kind) => {
  const errors = {};
  if (kind === 'domain') {
    if (!validateRequired(form.name)) errors.name = 'Domain name is required';
    if (!validateRequired(form.registrar)) errors.registrar = 'Registrar is required';
    if (!validateRequired(form.clientId)) errors.clientId = 'Client is required';
    if (!validateRequired(form.start)) errors.start = 'Start date is required';
    if (!validateRequired(form.expiry)) errors.expiry = 'Expiry date is required';
    if (form.start && form.expiry && form.start >= form.expiry) errors.expiry = 'Expiry must be after start date';
    if (!validateNumber(form.billedCost)) errors.billedCost = 'Billed cost must be a valid number';
    if (!validateNumber(form.purchasedCost)) errors.purchasedCost = 'Purchased cost must be a valid number';
  } else if (kind === 'server') {
    if (!validateRequired(form.label)) errors.label = 'Server label is required';
    if (!validateRequired(form.provider)) errors.provider = 'Provider is required';
    if (!validateRequired(form.clientId)) errors.clientId = 'Client is required';
    if (!validateRequired(form.ip)) errors.ip = 'IP address is required';
    if (!validateRequired(form.region)) errors.region = 'Region is required';
    if (!validateRequired(form.start)) errors.start = 'Start date is required';
    if (!validateRequired(form.expiry)) errors.expiry = 'Expiry date is required';
    if (form.start && form.expiry && form.start >= form.expiry) errors.expiry = 'Expiry must be after start date';
    if (!validateNumber(form.cpu) || form.cpu < 1) errors.cpu = 'CPU must be at least 1';
    if (!validateNumber(form.ram) || form.ram < 1) errors.ram = 'RAM must be at least 1 GB';
    if (!validateNumber(form.disk) || form.disk < 1) errors.disk = 'Disk must be at least 1 GB';
    if (!validateNumber(form.billedCost)) errors.billedCost = 'Billed cost must be a valid number';
    if (!validateNumber(form.purchasedCost)) errors.purchasedCost = 'Purchased cost must be a valid number';
  } else if (kind === 'client') {
    if (!validateRequired(form.name)) errors.name = 'Client name is required';
    if (!validateRequired(form.contact)) errors.contact = 'Contact person is required';
    if (!validateRequired(form.phone)) errors.phone = 'Phone is required';
    if (!validatePhone(form.phone)) errors.phone = 'Phone must be valid (at least 6 digits)';
  }
  return errors;
};

const Modal = ({ title, sub, onClose, children, footer }) => (
  <div className="scrim" onClick={(e) => { if (e.target.classList.contains('scrim')) onClose(); }}>
    <div className="modal" role="dialog">
      <div className="modal-head">
        <div>
          <h2>{title}</h2>
          {sub && <div className="sub">{sub}</div>}
        </div>
        <div style={{ marginLeft: 'auto' }}>
          <button className="btn ghost icon" onClick={onClose}><Icon name="x" size={16}/></button>
        </div>
      </div>
      <div className="modal-body">{children}</div>
      {footer && <div className="modal-foot">{footer}</div>}
    </div>
  </div>
);

const SubscriptionForm = ({ mode, kind, initial, pendingChanges, clients, providers, servers, domains, role, onClose, onSave, onApproveAndSave, onWithdraw, onDelete }) => {
  // Effective starting values (current + pending if any)
  const base = { ...(kind === 'domain' ? DOMAIN_DEFAULTS : SERVER_DEFAULTS), ...(initial || {}) };
  const startWith = pendingChanges ? { ...base, ...pendingChanges } : base;
  const [form, setForm] = React.useState(startWith);
  const [saving, setSaving] = React.useState(false);
  const set = (k, v) => setForm(f => ({ ...f, [k]: v }));

  // Determine diff vs current entity (to know which fields changed)
  const diff = {};
  if (initial) {
    Object.keys(form).forEach(k => {
      const a = form[k], b = initial[k];
      if (String(a ?? '') !== String(b ?? '')) diff[k] = form[k];
    });
  }
  const hasChanges = Object.keys(diff).length > 0 || mode === 'create';
  const errors = getValidationErrors(form, kind);
  const isValid = Object.keys(errors).length === 0;

  const handleSave = async () => {
    if (!isValid) return;
    setSaving(true);
    try {
      await onSave(form, diff);
    } finally {
      setSaving(false);
    }
  };

  const title = mode === 'create'
    ? `Add ${kind === 'domain' ? 'domain' : 'server'}`
    : `Edit ${kind === 'domain' ? 'domain' : 'server'}`;

  const sub = role === 'employee' && mode === 'edit'
    ? 'Changes need admin approval before going live.'
    : (mode === 'edit' ? 'Your changes will be saved immediately.' : null);

  const isEmployee = role === 'employee';

  return (
    <Modal title={title} sub={sub} onClose={onClose}
      footer={
        <>
          {mode === 'edit' && role === 'admin' && (
            <button className="btn danger" onClick={() => onDelete(initial)} style={{ marginRight: 'auto' }} disabled={saving}>
              <Icon name="trash" size={13}/> Delete
            </button>
          )}
          {pendingChanges && (
            <button className="btn" onClick={onWithdraw} style={{ marginRight: 'auto' }} disabled={saving}>
              Withdraw pending request
            </button>
          )}
          <button className="btn" onClick={onClose} disabled={saving}>Cancel</button>
          {role === 'admin' ? (
            <button className="btn brand" disabled={!hasChanges || !isValid || saving} onClick={handleSave}>
              <Icon name="check" size={13}/> {saving ? 'Saving…' : mode === 'create' ? 'Create' : 'Save changes'}
            </button>
          ) : (
            <button className="btn brand" disabled={!hasChanges || !isValid || saving} onClick={handleSave}>
              <Icon name="clock" size={13}/> {saving ? 'Submitting…' : mode === 'create' ? 'Submit for approval' : 'Submit edits'}
            </button>
          )}
        </>
      }
    >
      {pendingChanges && (
        <div className="notice">
          <Icon name="pending" size={14}/>
          <div>
            <strong>Has a pending request.</strong> {isEmployee ? 'Submitting again will replace the pending request — only the latest version stays in the queue.' : 'You can also approve directly from the Approvals page.'}
          </div>
        </div>
      )}
      {isEmployee && mode === 'edit' && !pendingChanges && (
        <div className="notice blue">
          <Icon name="info" size={14}/>
          <div>Edits don't go live until an admin approves. The current values remain visible to everyone else until then.</div>
        </div>
      )}
      {Object.keys(errors).length > 0 && (
        <div className="notice red">
          <Icon name="alert" size={14}/>
          <div>
            <strong>Fix the following before saving:</strong>
            <ul style={{ marginTop: 6, marginLeft: 20, fontSize: 13 }}>
              {Object.entries(errors).map(([field, msg]) => <li key={field}>{msg}</li>)}
            </ul>
          </div>
        </div>
      )}

      {kind === 'domain' ? (
        <>
          <div className="field-grid">
            <div className="field">
              <label>Domain name</label>
              <input value={form.name} onChange={(e) => set('name', e.target.value)} placeholder="example.com" />
            </div>
            <div className="field">
              <label>Registrar</label>
              <select value={form.registrar} onChange={(e) => set('registrar', e.target.value)}>
                {(providers ? providers.filter(p => p.kind === 'domain').map(p => p.name) : REGISTRARS).map(r => <option key={r}>{r}</option>)}
                {/* Include current value even if archived, so existing records still display correctly */}
                {initial?.registrar && providers && !providers.some(p => p.kind === 'domain' && p.name === initial.registrar) && (
                  <option key={initial.registrar} value={initial.registrar}>{initial.registrar} (archived)</option>
                )}
              </select>
            </div>
            <div className="field">
              <label>Start date</label>
              <input type="date" value={form.start} onChange={(e) => set('start', e.target.value)} />
            </div>
            <div className="field">
              <label>Expiry date</label>
              <input type="date" value={form.expiry} onChange={(e) => set('expiry', e.target.value)} />
            </div>
            <div className="field">
              <label>Billed to client (₹)</label>
              <input type="number" value={form.billedCost} onChange={(e) => set('billedCost', Number(e.target.value))} placeholder="999" />
            </div>
            <div className="field">
              <label>Purchased cost (₹)</label>
              <input type="number" value={form.purchasedCost} onChange={(e) => set('purchasedCost', Number(e.target.value))} placeholder="820" />
            </div>
            <div className="field">
              <label>Client</label>
              <select value={form.clientId} onChange={(e) => set('clientId', e.target.value)}>
                <option value="">— Select client —</option>
                {clients.map(c => <option key={c.id} value={c.id}>{c.name}</option>)}
              </select>
            </div>
          </div>
          <div className="field check">
            <input type="checkbox" id="ar" checked={!!form.autoRenew} onChange={(e) => set('autoRenew', e.target.checked)} />
            <label htmlFor="ar">Auto-renew enabled</label>
          </div>
          <div className="field">
            <label>Hosted on <span style={{ color: 'var(--text-muted)', fontWeight: 400 }}>(optional)</span></label>
            <select value={form.serverId || ''} onChange={(e) => set('serverId', e.target.value || null)}>
              <option value="">— Not hosted on a managed server / external —</option>
              {(() => {
                const groups = {};
                (servers || []).forEach(s => {
                  const c = clients.find(cl => cl.id === s.clientId);
                  const k = c?.name || 'Unassigned';
                  (groups[k] = groups[k] || []).push(s);
                });
                return Object.entries(groups).map(([clientName, list]) => (
                  <optgroup key={clientName} label={clientName}>
                    {list.map(s => (
                      <option key={s.id} value={s.id}>
                        {s.label} · {s.type === 'shared' ? 'Shared' : 'Individual'}
                      </option>
                    ))}
                  </optgroup>
                ));
              })()}
            </select>
            <span className="hint">A domain can be hosted on any server — including a shared server belonging to another client.</span>
          </div>
          <div className="field">
            <label>Role <span style={{ color: 'var(--text-muted)', fontWeight: 400 }}>(optional)</span></label>
            <div style={{ display: 'flex', gap: 8 }}>
              {[{ value: null, label: 'None' }, { value: 'frontend', label: 'Frontend' }, { value: 'backend', label: 'Backend' }].map(opt => (
                <button key={String(opt.value)} type="button"
                  className={`btn ${form.role === opt.value ? 'brand' : ''}`}
                  onClick={() => set('role', opt.value)}
                  style={{ flex: 1, justifyContent: 'center' }}>
                  {opt.label}
                </button>
              ))}
            </div>
            <span className="hint">Mark this domain as a frontend or backend endpoint to group it with its counterpart.</span>
          </div>
          {form.role && (
            <div className="field">
              <label>Group name <span style={{ color: 'var(--text-muted)', fontWeight: 400 }}>(optional)</span></label>
              <input
                list="domain-groups-list"
                value={form.groupId || ''}
                onChange={(e) => set('groupId', e.target.value)}
                placeholder="e.g. northwind-main"
              />
              <datalist id="domain-groups-list">
                {[...new Set((domains || [])
                  .filter(d => d.clientId === form.clientId && d.groupId && d.id !== (initial?.id))
                  .map(d => d.groupId)
                )].map(g => <option key={g} value={g} />)}
              </datalist>
              <span className="hint">Domains sharing the same group name are shown together. Pick an existing group or create a new one.</span>
            </div>
          )}
          <HealthMonitorSection form={form} set={set} kind="domain" />
          {form.serverId && (
            <div style={{ marginTop: 20, borderTop: '1px solid var(--border)', paddingTop: 16 }}>
              <div style={{ fontSize: 11, fontWeight: 600, letterSpacing: '0.06em', color: 'var(--text-muted)', textTransform: 'uppercase', marginBottom: 12 }}>
                PM2 Process
              </div>
              <div className="field">
                <label>PM2 app name <span style={{ color: 'var(--text-muted)', fontWeight: 400 }}>(optional)</span></label>
                <input
                  value={form.pm2AppName || ''}
                  onChange={(e) => set('pm2AppName', e.target.value)}
                  placeholder="e.g. my-app, api-server"
                />
                <span className="hint">The pm2 process name on the linked server. Enables restart/stop from the Telegram bot for this domain.</span>
              </div>
            </div>
          )}
        </>
      ) : (
        <>
          <div className="field-grid">
            <div className="field">
              <label>Server label</label>
              <input value={form.label} onChange={(e) => set('label', e.target.value)} placeholder="nw-prod-01" />
            </div>
            <div className="field">
              <label>Provider</label>
              <select value={form.provider} onChange={(e) => set('provider', e.target.value)}>
                {(providers ? providers.filter(p => p.kind === 'server').map(p => p.name) : PROVIDERS).map(p => <option key={p}>{p}</option>)}
                {initial?.provider && providers && !providers.some(p => p.kind === 'server' && p.name === initial.provider) && (
                  <option key={initial.provider} value={initial.provider}>{initial.provider} (archived)</option>
                )}
              </select>
            </div>
            <div className="field">
              <label>IP address</label>
              <input value={form.ip} onChange={(e) => set('ip', e.target.value)} placeholder="0.0.0.0" />
            </div>
            <div className="field">
              <label>Panel domain <span style={{ color: 'var(--text-muted)', fontWeight: 400 }}>(optional)</span></label>
              <input value={form.panelDomain} onChange={(e) => set('panelDomain', e.target.value)} placeholder="panel.example.com" />
            </div>
            <div className="field">
              <label>Region</label>
              <input value={form.region} onChange={(e) => set('region', e.target.value)} placeholder="Mumbai, IN" />
            </div>
            <div className="field">
              <label>Operating system</label>
              <select value={form.os} onChange={(e) => set('os', e.target.value)}>
                {OSES.map(o => <option key={o}>{o}</option>)}
              </select>
            </div>
            <div className="field">
              <label>Client</label>
              <select value={form.clientId} onChange={(e) => set('clientId', e.target.value)}>
                <option value="">— Select client —</option>
                {clients.map(c => <option key={c.id} value={c.id}>{c.name}</option>)}
              </select>
            </div>
          </div>
          <div className="field">
            <label>Server type</label>
            <div style={{ display: 'flex', gap: 8 }}>
              <button type="button"
                className={`btn ${form.type === 'individual' ? 'brand' : ''}`}
                onClick={() => set('type', 'individual')}
                style={{ flex: 1, justifyContent: 'center' }}>
                <Icon name="shield" size={13}/> Individual
              </button>
              <button type="button"
                className={`btn ${form.type === 'shared' ? 'brand' : ''}`}
                onClick={() => set('type', 'shared')}
                style={{ flex: 1, justifyContent: 'center' }}>
                <Icon name="clients" size={13}/> Shared
              </button>
            </div>
            <span className="hint">{form.type === 'shared' ? 'Multiple clients’ sites can sit on this server.' : 'Dedicated to a single client.'}</span>
          </div>
          <div className="field-grid-3">
            <div className="field">
              <label>CPU <span style={{ color: 'var(--text-muted)', fontWeight: 400 }}>(vCPU)</span></label>
              <input type="number" min="1" value={form.cpu} onChange={(e) => set('cpu', Number(e.target.value))} placeholder="2" />
            </div>
            <div className="field">
              <label>RAM <span style={{ color: 'var(--text-muted)', fontWeight: 400 }}>(GB)</span></label>
              <input type="number" min="1" value={form.ram} onChange={(e) => set('ram', Number(e.target.value))} placeholder="4" />
            </div>
            <div className="field">
              <label>Disk <span style={{ color: 'var(--text-muted)', fontWeight: 400 }}>(GB)</span></label>
              <input type="number" min="1" value={form.disk} onChange={(e) => set('disk', Number(e.target.value))} placeholder="80" />
            </div>
          </div>
          <div className="field-grid">
            <div className="field"><label>Start date</label><input type="date" value={form.start} onChange={(e) => set('start', e.target.value)} /></div>
            <div className="field"><label>Expiry / renewal</label><input type="date" value={form.expiry} onChange={(e) => set('expiry', e.target.value)} /></div>
          </div>
          <div className="field check">
            <input type="checkbox" id="server-ar" checked={!!form.autoRenew} onChange={(e) => set('autoRenew', e.target.checked)} />
            <label htmlFor="server-ar">Auto-renew enabled</label>
          </div>
          <div className="field-grid">
            <div className="field">
              <label>Billed to client (₹)</label>
              <input type="number" value={form.billedCost} onChange={(e) => set('billedCost', Number(e.target.value))} placeholder="1800" />
            </div>
            <div className="field">
              <label>Purchased cost (₹)</label>
              <input type="number" value={form.purchasedCost} onChange={(e) => set('purchasedCost', Number(e.target.value))} placeholder="1500" />
            </div>
          </div>
          <HealthMonitorSection form={form} set={set} kind="server" />
          <SshConfigSection form={form} set={set} />
        </>
      )}
    </Modal>
  );
};

const ClientForm = ({ mode, initial, onClose, onSave }) => {
  const [form, setForm] = React.useState({ ...CLIENT_DEFAULTS, ...(initial || {}) });
  const [saving, setSaving] = React.useState(false);
  const set = (k, v) => setForm(f => ({ ...f, [k]: v }));

  const errors = getValidationErrors(form, 'client');
  const isValid = Object.keys(errors).length === 0;
  const hasChanges = initial ? Object.keys(form).some(k => form[k] !== initial[k]) : true;

  const handleSave = async () => {
    if (!isValid) return;
    setSaving(true);
    try {
      await onSave(form);
    } finally {
      setSaving(false);
    }
  };

  return (
    <Modal
      title={mode === 'create' ? 'Add client' : 'Edit client'}
      onClose={onClose}
      footer={
        <>
          <button className="btn" onClick={onClose} disabled={saving}>Cancel</button>
          <button className="btn brand" disabled={!hasChanges || !isValid || saving} onClick={handleSave}>
            <Icon name="check" size={13}/> {saving ? 'Saving…' : mode === 'create' ? 'Create' : 'Save'}
          </button>
        </>
      }
    >
      {Object.keys(errors).length > 0 && (
        <div className="notice red" style={{ marginBottom: 14 }}>
          <Icon name="alert" size={14}/>
          <div>
            <strong>Fix the following:</strong>
            <ul style={{ marginTop: 6, marginLeft: 20, fontSize: 13 }}>
              {Object.entries(errors).map(([field, msg]) => <li key={field}>{msg}</li>)}
            </ul>
          </div>
        </div>
      )}
      <div className="field-grid">
        <div className="field">
          <label>Client name *</label>
          <input value={form.name} onChange={(e) => set('name', e.target.value)} placeholder="Acme Corp" style={{ borderColor: errors.name ? 'var(--red)' : undefined }} />
          {errors.name && <span style={{ color: 'var(--red)', fontSize: 12, marginTop: 4 }}>{errors.name}</span>}
        </div>
        <div className="field">
          <label>Contact person *</label>
          <input value={form.contact} onChange={(e) => set('contact', e.target.value)} placeholder="John Smith" style={{ borderColor: errors.contact ? 'var(--red)' : undefined }} />
          {errors.contact && <span style={{ color: 'var(--red)', fontSize: 12, marginTop: 4 }}>{errors.contact}</span>}
        </div>
        <div className="field">
          <label>Phone *</label>
          <input value={form.phone} onChange={(e) => set('phone', e.target.value)} placeholder="+91 9876543210" style={{ borderColor: errors.phone ? 'var(--red)' : undefined }} />
          {errors.phone && <span style={{ color: 'var(--red)', fontSize: 12, marginTop: 4 }}>{errors.phone}</span>}
        </div>
        <div className="field">
          <label>Tag <span style={{ color: 'var(--text-muted)', fontWeight: 400 }}>(optional)</span></label>
          <input value={form.tag} onChange={(e) => set('tag', e.target.value)} placeholder="Premium, VIP, etc." />
        </div>
        <div className="field">
          <label>Email <span style={{ color: 'var(--text-muted)', fontWeight: 400 }}>(for expiry notifications)</span></label>
          <input value={form.email || ''} onChange={(e) => set('email', e.target.value)} placeholder="client@example.com" type="email" />
          <span className="hint">Used to send expiry notification emails via the ✉ button on subscriptions.</span>
        </div>
      </div>
    </Modal>
  );
};

window.SubscriptionForm = SubscriptionForm;
window.ClientForm = ClientForm;
window.Modal = Modal;
