import { router, useForm } from '@inertiajs/react';
import { useEffect, useMemo, useRef, useState, type FormEvent, type ReactNode } from 'react';
import { AppLayout } from '@/Components/Layout/AppLayout';

type ServerStatus = 'active' | 'draining' | 'offline';
type ActionStatus = 'queued' | 'running' | 'succeeded' | 'failed';
type ActionName = 'probe' | 'install' | 'restart' | 'logs' | 'enable' | 'drain' | 'disable';

type MediaServer = {
  id: number;
  name: string;
  kind: string;
  host: string;
  port: number;
  scheme: string;
  realm: string | null;
  region: string | null;
  publicIp: string | null;
  capacity: number;
  currentLoad: number;
  loadPercent: number;
  priority: number;
  status: ServerStatus;
  lastHealthAt: string | null;
  lastHealthOk: boolean;
  lastHealthNote: string | null;
  sshHost: string | null;
  sshPort: number;
  sshUser: string;
  sshConfigured: boolean;
  sshAuth: 'password' | 'key' | null;
  sshHostFingerprint: string | null;
  lastSshAt: string | null;
  lastSshOk: boolean;
  lastSshNote: string | null;
  busy: boolean;
};

type ServerAction = {
  id: number;
  serverId: number;
  serverName: string;
  userName: string;
  action: ActionName;
  status: ActionStatus;
  output: string | null;
  createdAt: string;
  startedAt: string | null;
  finishedAt: string | null;
};

type Props = {
  servers: MediaServer[];
  actions: ServerAction[];
  summary: { total: number; healthy: number; active: number; capacity: number; load: number };
};

type ServerForm = {
  name: string;
  host: string;
  port: string;
  realm: string;
  region: string;
  public_ip: string;
  capacity: string;
  priority: string;
  ssh_host: string;
  ssh_port: string;
  ssh_user: string;
  ssh_auth_type: 'password' | 'key';
  ssh_password: string;
  ssh_private_key: string;
  ssh_key_passphrase: string;
  ssh_host_fingerprint: string;
};

type IconName = 'server' | 'plus' | 'pulse' | 'play' | 'refresh' | 'logs' | 'edit' | 'trash' | 'pause' | 'power' | 'close' | 'key' | 'shield' | 'users' | 'route';

const iconPaths: Record<IconName, ReactNode> = {
  server: <><rect x="4" y="3" width="16" height="6" rx="2"/><rect x="4" y="15" width="16" height="6" rx="2"/><path d="M8 6h.01M8 18h.01M12 6h5M12 18h5M6 9v6M18 9v6"/></>,
  plus: <path d="M12 5v14M5 12h14"/>,
  pulse: <path d="M3 12h4l2.2-6 4 12 2.2-6H21"/>,
  play: <><path d="m9 7 8 5-8 5V7Z"/><circle cx="12" cy="12" r="9"/></>,
  refresh: <><path d="M20 7v5h-5M4 17v-5h5"/><path d="M18.3 9A7 7 0 0 0 6.1 6.1L4 8m16 8-2.1 1.9A7 7 0 0 1 5.7 15"/></>,
  logs: <><path d="M5 4h14v16H5z"/><path d="M8 8h8M8 12h8M8 16h5"/></>,
  edit: <><path d="M4 20h4l11-11-4-4L4 16v4Z"/><path d="m13.5 6.5 4 4"/></>,
  trash: <><path d="M4 7h16M9 7V4h6v3M7 7l1 13h8l1-13M10 11v5M14 11v5"/></>,
  pause: <><rect x="6" y="5" width="4" height="14" rx="1"/><rect x="14" y="5" width="4" height="14" rx="1"/></>,
  power: <><path d="M12 3v9"/><path d="M7.1 5.7a8 8 0 1 0 9.8 0"/></>,
  close: <path d="m6 6 12 12M18 6 6 18"/>,
  key: <><circle cx="8" cy="15" r="4"/><path d="m11 12 8-8M15 8l3 3M17 6l2 2"/></>,
  shield: <><path d="M12 3 5 6v5c0 4.6 2.8 8 7 10 4.2-2 7-5.4 7-10V6l-7-3Z"/><path d="m9 12 2 2 4-5"/></>,
  users: <><circle cx="9" cy="8" r="3"/><path d="M3 20v-2a6 6 0 0 1 12 0v2M16 5.5a3 3 0 0 1 0 5.5M17 14a5 5 0 0 1 4 5"/></>,
  route: <><circle cx="6" cy="6" r="2"/><circle cx="18" cy="18" r="2"/><path d="M8 6h4a3 3 0 0 1 3 3v6M12 12l3 3 3-3"/></>,
};

function Icon({ name, size = 18 }: { name: IconName; size?: number }) {
  return <svg className="ms-icon" width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">{iconPaths[name]}</svg>;
}

const emptyForm: ServerForm = {
  name: '', host: '', port: '3478', realm: 'mydaneshyar.ir', region: '', public_ip: '',
  capacity: '80', priority: '20', ssh_host: '', ssh_port: '22', ssh_user: 'root',
  ssh_auth_type: 'password',
  ssh_password: '', ssh_private_key: '', ssh_key_passphrase: '', ssh_host_fingerprint: '',
};

const actionLabels: Record<ActionName, string> = {
  probe: 'بررسی اتصال', install: 'نصب / ترمیم', restart: 'راه‌اندازی مجدد', logs: 'مشاهده لاگ',
  enable: 'فعال‌سازی', drain: 'تخلیه', disable: 'غیرفعال‌سازی',
};

const statusLabels: Record<ServerStatus, string> = { active: 'فعال', draining: 'در حال تخلیه', offline: 'خارج از سرویس' };
const actionStatusLabels: Record<ActionStatus, string> = { queued: 'در صف', running: 'در حال اجرا', succeeded: 'موفق', failed: 'ناموفق' };

function Stat({ icon, value, label, tone }: { icon: IconName; value: string | number; label: string; tone: string }) {
  return <article className={`ms-stat tone-${tone}`}><span><Icon name={icon} size={22}/></span><div><strong>{typeof value === 'number' ? value.toLocaleString('fa-IR') : value}</strong><small>{label}</small></div></article>;
}

export default function MediaServers({ servers, actions, summary }: Props) {
  const [modalOpen, setModalOpen] = useState(false);
  const [editingId, setEditingId] = useState<number | null>(null);
  const [expandedAction, setExpandedAction] = useState<number | null>(actions.find((item) => item.output)?.id ?? null);
  const [healthMessage, setHealthMessage] = useState<string | null>(null);
  const availabilityRef = useRef(new Map(servers.map((server) => [server.id, server.lastHealthOk && server.status === 'active'])));
  const form = useForm<ServerForm>(emptyForm);
  const hasPending = useMemo(() => servers.some((server) => server.busy) || actions.some((item) => item.status === 'queued' || item.status === 'running'), [servers, actions]);

  useEffect(() => {
    const refresh = () => {
      if (document.visibilityState === 'visible') {
        router.reload({ only: ['servers', 'actions', 'summary'] });
      }
    };
    const timer = window.setInterval(refresh, 5000);
    return () => window.clearInterval(timer);
  }, []);

  useEffect(() => {
    const recovered = servers.find((server) => (
      availabilityRef.current.get(server.id) === false
      && server.lastHealthOk
      && server.status === 'active'
    ));
    availabilityRef.current = new Map(servers.map((server) => [server.id, server.lastHealthOk && server.status === 'active']));
    if (recovered) setHealthMessage(`سرور «${recovered.name}» اکنون سالم و آماده پذیرش کلاس است.`);
  }, [servers]);

  useEffect(() => {
    if (!healthMessage) return;
    const timer = window.setTimeout(() => setHealthMessage(null), 7000);
    return () => window.clearTimeout(timer);
  }, [healthMessage]);

  function openCreate() {
    setEditingId(null);
    form.clearErrors();
    form.setData({ ...emptyForm, priority: String((servers.length + 1) * 10) });
    setModalOpen(true);
  }

  function openEdit(server: MediaServer) {
    setEditingId(server.id);
    form.clearErrors();
    form.setData({
      name: server.name,
      host: server.host,
      port: String(server.port),
      realm: server.realm ?? '',
      region: server.region ?? '',
      public_ip: server.publicIp ?? '',
      capacity: String(server.capacity),
      priority: String(server.priority),
      ssh_host: server.sshHost ?? server.host,
      ssh_port: String(server.sshPort),
      ssh_user: server.sshUser,
      ssh_auth_type: server.sshAuth ?? 'password',
      ssh_password: '',
      ssh_private_key: '',
      ssh_key_passphrase: '',
      ssh_host_fingerprint: server.sshHostFingerprint ?? '',
    });
    setModalOpen(true);
  }

  function closeModal() {
    if (form.processing) return;
    finishModal();
  }

  function finishModal() {
    setModalOpen(false);
    setEditingId(null);
    form.clearErrors();
  }

  function submit(event: FormEvent) {
    event.preventDefault();
    const options = { preserveScroll: true, onSuccess: finishModal };
    if (editingId) form.put(`/super-admin/media-servers/${editingId}`, options);
    else form.post('/super-admin/media-servers', options);
  }

  function runAction(server: MediaServer, action: ActionName) {
    const confirmation: Partial<Record<ActionName, string>> = {
      install: `coturn روی «${server.name}» نصب یا ترمیم شود؟`,
      restart: `سرویس coturn روی «${server.name}» راه‌اندازی مجدد شود؟ ارتباط‌های همان لحظه ممکن است کوتاه قطع شوند.`,
      drain: `«${server.name}» تخلیه شود؟ کلاس‌های فعلی می‌مانند ولی کلاس جدید به آن متصل نمی‌شود.`,
      disable: `«${server.name}» از مسیریابی خارج شود؟`,
      enable: `«${server.name}» برای کلاس‌های جدید فعال شود؟`,
    };
    if (confirmation[action] && !window.confirm(confirmation[action])) return;
    router.post(`/super-admin/media-servers/${server.id}/actions/${action}`, {}, { preserveScroll: true });
  }

  function remove(server: MediaServer) {
    if (!window.confirm(`«${server.name}» فقط از سامانه حذف شود؟ ماشین مجازی حذف نخواهد شد.`)) return;
    router.delete(`/super-admin/media-servers/${server.id}`, { preserveScroll: true });
  }

  return (
    <AppLayout title="سرورهای رسانه">
      <div className="page-stack ms-page">
        <section className="ms-hero">
          <div className="ms-hero-mark"><Icon name="server" size={30}/><span className={summary.healthy === summary.total && summary.total > 0 ? 'is-ok' : ''}/></div>
          <div className="ms-hero-copy">
            <p className="ms-eyebrow">زیرساخت کلاس آنلاین</p>
            <h2>سرورهای رسانه</h2>
            <p>نصب، پایش، توزیع بار و نگهداری TURN از داخل پنل مدیر کل</p>
          </div>
          <button type="button" className="btn btn-primary ms-add" onClick={openCreate}><Icon name="plus"/>افزودن سرور</button>
        </section>

        <section className="ms-stats" aria-label="خلاصه سرورها">
          <Stat icon="server" value={summary.total} label="سرور ثبت‌شده" tone="primary"/>
          <Stat icon="shield" value={`${summary.healthy.toLocaleString('fa-IR')} / ${summary.total.toLocaleString('fa-IR')}`} label="سالم و در دسترس" tone="success"/>
          <Stat icon="users" value={`${summary.load.toLocaleString('fa-IR')} / ${summary.capacity.toLocaleString('fa-IR')}`} label="بار زنده / ظرفیت" tone="violet"/>
          <Stat icon="route" value={summary.active} label="فعال برای کلاس جدید" tone="info"/>
        </section>

        <aside className="ms-keepalive"><span><Icon name="power"/></span><div><strong>ماندگاری و پایش خودکار سرویس</strong><p>coturn پس از ری‌استارت سرور خودکار بالا می‌آید؛ سلامت همه گره‌ها هر ۵ ثانیه بررسی و همین صفحه زنده بروزرسانی می‌شود.</p></div></aside>

        {healthMessage && <aside className="ms-health-success" role="status"><span><Icon name="shield"/></span><div><strong>اتصال موفق شد</strong><p>{healthMessage}</p></div></aside>}

        <section className="ms-section-head"><div><h3>گره‌های فعال</h3><p>هر کلاس روی کم‌بارترین سرور سالم ثابت می‌ماند.</p></div><span className="ms-live"><i/>{hasPending ? 'در حال اجرای عملیات؛ پایش هر ۵ ثانیه' : 'پایش زنده هر ۵ ثانیه'}</span></section>

        {servers.length === 0 ? (
          <section className="ms-empty"><span><Icon name="server" size={34}/></span><h3>هنوز سروری ثبت نشده است</h3><p>سرور Ubuntu خود را اضافه کنید و سپس «نصب / ترمیم» را بزنید.</p><button className="btn btn-primary" onClick={openCreate}><Icon name="plus"/>افزودن اولین سرور</button></section>
        ) : (
          <section className="ms-server-grid">
            {servers.map((server) => {
              const healthy = server.lastHealthOk && server.status !== 'offline';
              return (
                <article className={`ms-server-card status-${server.status}${server.busy ? ' is-busy' : ''}`} key={server.id}>
                  <header className="ms-server-head">
                    <span className={`ms-server-glyph ${healthy ? 'is-healthy' : ''}`}><Icon name="server" size={23}/><i/></span>
                    <div><h3>{server.name}</h3><p><span dir="ltr">{server.host}:{server.port}</span>{server.region && <> · {server.region}</>}</p></div>
                    <span className={`ms-status status-${server.status}`}>{server.busy && <i className="ms-spinner"/>}{server.busy ? 'در حال اجرا' : statusLabels[server.status]}</span>
                  </header>

                  <div className="ms-load-row"><div><span>بار فعلی</span><strong>{server.currentLoad.toLocaleString('fa-IR')} از {server.capacity.toLocaleString('fa-IR')}</strong></div><b>{server.loadPercent.toLocaleString('fa-IR')}٪</b></div>
                  <div className="ms-progress"><span style={{ width: `${server.loadPercent}%` }}/></div>

                  <dl className="ms-server-facts">
                    <div><dt>سلامت TURN</dt><dd className={server.lastHealthOk ? 'ok' : 'bad'}><i/>{server.lastHealthOk ? 'سالم' : 'نیاز به بررسی'}</dd></div>
                    <div><dt>آخرین بررسی</dt><dd>{server.lastHealthAt ?? 'هنوز انجام نشده'}</dd></div>
                    <div><dt>دسترسی SSH</dt><dd className={server.sshConfigured ? '' : 'bad'}>{server.sshConfigured ? `${server.sshUser}@${server.sshHost ?? server.host}:${server.sshPort}` : 'تنظیم نشده'}</dd></div>
                    <div><dt>روش ورود</dt><dd>{server.sshAuth === 'key' ? 'کلید خصوصی رمزنگاری‌شده' : server.sshAuth === 'password' ? 'رمز رمزنگاری‌شده' : '—'}</dd></div>
                  </dl>

                  {server.lastHealthNote && <p className="ms-note" title={server.lastHealthNote}>{server.lastHealthNote}</p>}

                  <div className="ms-primary-actions">
                    <button className="btn btn-primary" disabled={server.busy || !server.sshConfigured} onClick={() => runAction(server, 'install')}><Icon name="play"/>نصب / ترمیم</button>
                    <button className="btn btn-soft" disabled={server.busy || !server.sshConfigured} onClick={() => runAction(server, 'probe')}><Icon name="pulse"/>بررسی</button>
                    <button className="btn btn-ghost" disabled={server.busy || !server.sshConfigured} onClick={() => runAction(server, 'restart')} title="راه‌اندازی مجدد coturn"><Icon name="refresh"/><span>ری‌استارت</span></button>
                    <button className="btn btn-ghost ms-icon-button" disabled={server.busy || !server.sshConfigured} onClick={() => runAction(server, 'logs')} title="دریافت آخرین لاگ‌ها"><Icon name="logs"/></button>
                  </div>
                  <div className="ms-secondary-actions">
                    <button type="button" onClick={() => openEdit(server)}><Icon name="edit"/>ویرایش</button>
                    {server.status === 'active' ? <button type="button" onClick={() => runAction(server, 'drain')}><Icon name="pause"/>تخلیه</button> : <button type="button" onClick={() => runAction(server, 'enable')} disabled={!server.lastHealthOk}><Icon name="power"/>فعال‌سازی</button>}
                    {server.status !== 'offline' && <button type="button" onClick={() => runAction(server, 'disable')}><Icon name="power"/>خارج از سرویس</button>}
                    <button type="button" className="danger" onClick={() => remove(server)} disabled={server.busy}><Icon name="trash"/>حذف</button>
                  </div>
                </article>
              );
            })}
          </section>
        )}

        <section className="ms-history panel-card">
          <div className="ms-history-head"><div><h3>تاریخچه عملیات</h3><p>خروجی امن آخرین فرمان‌های کنترل‌شده</p></div><button className="btn btn-ghost btn-sm" onClick={() => router.reload({ only: ['servers', 'actions', 'summary'] })}><Icon name="refresh"/>بروزرسانی</button></div>
          {actions.length === 0 ? <p className="ms-history-empty">هنوز عملیاتی اجرا نشده است.</p> : <div className="ms-action-list">{actions.map((item) => (
            <article className={`ms-action action-${item.status}`} key={item.id}>
              <button type="button" className="ms-action-summary" onClick={() => setExpandedAction(expandedAction === item.id ? null : item.id)}>
                <span className="ms-action-icon">{item.status === 'running' || item.status === 'queued' ? <i className="ms-spinner"/> : <Icon name={item.status === 'succeeded' ? 'shield' : 'logs'}/>}</span>
                <span className="ms-action-copy"><strong>{actionLabels[item.action]} · {item.serverName}</strong><small>{item.userName} · {item.createdAt}</small></span>
                <span className={`ms-action-status ${item.status}`}>{actionStatusLabels[item.status]}</span>
              </button>
              {expandedAction === item.id && item.output && <pre>{item.output}</pre>}
            </article>
          ))}</div>}
        </section>
      </div>

      {modalOpen && <div className="modal-overlay ms-modal-overlay" role="presentation" onMouseDown={(event) => { if (event.currentTarget === event.target) closeModal(); }}>
        <form className="modal-box ms-modal" onSubmit={submit}>
          <header className="modal-head"><div><p className="ms-eyebrow">تنظیمات امن</p><h2>{editingId ? 'ویرایش سرور رسانه' : 'افزودن سرور رسانه'}</h2></div><button type="button" className="modal-close" onClick={closeModal} aria-label="بستن"><Icon name="close"/></button></header>
          <p className="modal-hint"><Icon name="shield"/> اطلاعات SSH با APP_KEY رمزنگاری می‌شود و هیچ‌وقت به مرورگر بازگردانده نمی‌شود. کاربر غیر root باید sudo بدون رمز داشته باشد.</p>

          <fieldset className="ms-fieldset"><legend><Icon name="server"/>رسانه و توزیع بار</legend><div className="ms-form-grid">
            <Field label="نام نمایشی" error={form.errors.name}><input value={form.data.name} onChange={(e) => form.setData('name', e.target.value)} placeholder="TURN آلمان ۲" autoFocus/></Field>
            <Field label="آدرس عمومی TURN" error={form.errors.host}><input dir="ltr" value={form.data.host} onChange={(e) => { form.setData('host', e.target.value); if (!form.data.ssh_host) form.setData('ssh_host', e.target.value); }} placeholder="203.0.113.20"/></Field>
            <Field label="پورت TURN" error={form.errors.port}><input dir="ltr" type="number" min="1" max="65535" value={form.data.port} onChange={(e) => form.setData('port', e.target.value)}/></Field>
            <Field label="Realm" error={form.errors.realm}><input dir="ltr" value={form.data.realm} onChange={(e) => form.setData('realm', e.target.value)} placeholder="mydaneshyar.ir"/></Field>
            <Field label="ناحیه" error={form.errors.region}><input value={form.data.region} onChange={(e) => form.setData('region', e.target.value)} placeholder="de-fsn1"/></Field>
            <Field label="IP عمومی در حالت NAT" error={form.errors.public_ip} hint="برای VPS عادی خالی بماند"><input dir="ltr" value={form.data.public_ip} onChange={(e) => form.setData('public_ip', e.target.value)} placeholder="اختیاری"/></Field>
            <Field label="ظرفیت شرکت‌کننده" error={form.errors.capacity}><input dir="ltr" type="number" min="1" value={form.data.capacity} onChange={(e) => form.setData('capacity', e.target.value)}/></Field>
            <Field label="اولویت" error={form.errors.priority} hint="عدد کمتر در تساوی زودتر انتخاب می‌شود"><input dir="ltr" type="number" min="1" value={form.data.priority} onChange={(e) => form.setData('priority', e.target.value)}/></Field>
          </div></fieldset>

          <fieldset className="ms-fieldset"><legend><Icon name="key"/>اتصال SSH</legend><div className="ms-form-grid">
            <Field label="آدرس SSH" error={form.errors.ssh_host}><input dir="ltr" value={form.data.ssh_host} onChange={(e) => form.setData('ssh_host', e.target.value)} placeholder="همان IP سرور"/></Field>
            <Field label="پورت SSH" error={form.errors.ssh_port}><input dir="ltr" type="number" min="1" max="65535" value={form.data.ssh_port} onChange={(e) => form.setData('ssh_port', e.target.value)}/></Field>
            <Field label="نام کاربری SSH" error={form.errors.ssh_user}><input dir="ltr" value={form.data.ssh_user} onChange={(e) => form.setData('ssh_user', e.target.value)} autoComplete="username"/></Field>
            <Field label="روش ورود" error={form.errors.ssh_auth_type}><select value={form.data.ssh_auth_type} onChange={(e) => form.setData('ssh_auth_type', e.target.value as 'password' | 'key')}><option value="password">رمز عبور</option><option value="key">کلید خصوصی</option></select></Field>
            <Field label={editingId ? 'رمز SSH جدید' : 'رمز SSH'} error={form.errors.ssh_password} hint={editingId ? 'برای نگه‌داشتن رمز فعلی خالی بگذارید' : 'یا کلید خصوصی وارد کنید'}><input dir="ltr" type="password" value={form.data.ssh_password} onChange={(e) => form.setData('ssh_password', e.target.value)} autoComplete="new-password"/></Field>
            <Field wide label="اثر انگشت میزبان" error={form.errors.ssh_host_fingerprint} hint="اختیاری؛ در اولین اتصال موفق ذخیره و بعد از آن اجباری می‌شود"><input dir="ltr" value={form.data.ssh_host_fingerprint} onChange={(e) => form.setData('ssh_host_fingerprint', e.target.value)} placeholder="SHA256:..."/></Field>
            <Field wide label={editingId ? 'کلید خصوصی جدید' : 'کلید خصوصی'} error={form.errors.ssh_private_key} hint={editingId ? 'برای نگه‌داشتن کلید فعلی خالی بگذارید' : 'PEM/OpenSSH؛ در صورت استفاده از رمز می‌تواند خالی باشد'}><textarea dir="ltr" rows={4} value={form.data.ssh_private_key} onChange={(e) => form.setData('ssh_private_key', e.target.value)} placeholder="-----BEGIN OPENSSH PRIVATE KEY-----"/></Field>
            <Field wide label="عبارت عبور کلید خصوصی" error={form.errors.ssh_key_passphrase} hint="فقط اگر کلید خصوصی رمز دارد"><input dir="ltr" type="password" value={form.data.ssh_key_passphrase} onChange={(e) => form.setData('ssh_key_passphrase', e.target.value)} autoComplete="new-password"/></Field>
          </div></fieldset>

          <footer className="ms-modal-actions"><button type="button" className="btn btn-ghost" onClick={closeModal}>انصراف</button><button type="submit" className="btn btn-primary" disabled={form.processing}><Icon name="shield"/>{editingId ? 'ذخیره تغییرات' : 'ثبت امن سرور'}</button></footer>
        </form>
      </div>}
    </AppLayout>
  );
}

function Field({ label, error, hint, wide = false, children }: { label: string; error?: string; hint?: string; wide?: boolean; children: ReactNode }) {
  return <label className={`ms-field${wide ? ' is-wide' : ''}`}><span>{label}</span>{children}{hint && <small>{hint}</small>}{error && <small className="field-error">{error}</small>}</label>;
}
