import React, { useCallback, useEffect, useState } from 'react';
import {
  FiRefreshCw, FiList, FiLogOut, FiSettings, FiKey, FiTrash2, FiPlus, FiInbox,
  FiUsers, FiUser, FiHardDrive, FiDollarSign, FiActivity,
} from 'react-icons/fi';

import Login from './components/Login';
import Toast from './components/Toast';
import LoadingOverlay from './components/LoadingOverlay';
import UsageBar, { formatBytes } from './components/UsageBar';
import MailboxSettingsModal from './components/MailboxSettingsModal';
import NewMailboxModal from './components/NewMailboxModal';
import PasswordResetModal from './components/PasswordResetModal';
import ConfirmDialog from './components/ConfirmDialog';
import AuditLogModal from './components/AuditLogModal';
import AdminUsersModal from './components/AdminUsersModal';
import ChangeMyPasswordModal from './components/ChangeMyPasswordModal';
import DomainQuotaModal from './components/DomainQuotaModal';
import BillingModal from './components/BillingModal';
import HealthModal from './components/HealthModal';
import HealthBanner from './components/HealthBanner';

import { authAPI, domainsAPI, mailboxesAPI, healthAPI } from './services/api';

function App() {
  const [user, setUser] = useState(null);
  const [bootChecked, setBootChecked] = useState(false);

  const [domains, setDomains] = useState([]);
  const [selectedDomain, setSelectedDomain] = useState(null);
  const [mailboxes, setMailboxes] = useState([]);

  const [busyMessage, setBusyMessage] = useState('');
  const [toast, setToast] = useState(null);

  const [settingsTarget, setSettingsTarget] = useState(null);
  const [pwTarget, setPwTarget] = useState(null);
  const [deleteTarget, setDeleteTarget] = useState(null);
  const [showNew, setShowNew] = useState(false);
  const [showAudit, setShowAudit] = useState(false);
  const [showAdmins, setShowAdmins] = useState(false);
  const [showChangePw, setShowChangePw] = useState(false);
  const [showDomainQuota, setShowDomainQuota] = useState(false);
  const [showBilling, setShowBilling] = useState(false);
  const [showHealth, setShowHealth] = useState(false);

  // Persisted health status for the currently selected domain (drives the banner).
  const [healthStatus, setHealthStatus] = useState(null);

  const showToast = useCallback((message, type = 'success') => {
    setToast({ message, type });
  }, []);

  const isSuperAdmin = user?.role === 'super_admin';
  const hideDomainList = !isSuperAdmin && domains.length <= 1;

  const loadDomains = useCallback(async (resync = false) => {
    const list = await domainsAPI.list(resync);
    setDomains(list);
    return list;
  }, []);

  const loadMailboxes = useCallback(async (domain, refreshQuota = false) => {
    if (!domain) { setMailboxes([]); return; }
    const list = await mailboxesAPI.list(domain, refreshQuota);
    setMailboxes(list);
  }, []);

  // Load (or re-load) the persisted health status for a domain.
  // Cheap call — just reads from PostgreSQL, no checks are run.
  const loadHealthStatus = useCallback(async (domain) => {
    if (!domain) { setHealthStatus(null); return; }
    try {
      const status = await healthAPI.getStatus(domain);
      setHealthStatus(status); // null if never checked, that's fine
    } catch (err) {
      // Silent: don't block the UI just because health status load failed.
      console.warn('Failed to load health status:', err);
      setHealthStatus(null);
    }
  }, []);

  useEffect(() => {
    (async () => {
      try {
        const me = await authAPI.me();
        setUser(me);
      } catch {
        setUser(null);
      } finally {
        setBootChecked(true);
      }
    })();
  }, []);

  useEffect(() => {
    if (!user) return;
    (async () => {
      setBusyMessage('Loading domains...');
      try {
        const list = await loadDomains(isSuperAdmin);
        const first = list[0]?.domain || null;
        setSelectedDomain(first);
        if (first) {
          setBusyMessage('Refreshing quotas...');
          await loadMailboxes(first, true);
          await loadHealthStatus(first);
        }
      } catch (err) {
        showToast(`Failed to load: ${err.message}`, 'error');
      } finally {
        setBusyMessage('');
      }
    })();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [user]);

  const selectDomain = async (domain) => {
    if (domain === selectedDomain) return;
    setSelectedDomain(domain);
    setBusyMessage('Loading mailboxes...');
    try {
      await loadMailboxes(domain, true);
      await loadHealthStatus(domain);
    } catch (err) {
      showToast(`Failed to load mailboxes: ${err.message}`, 'error');
    } finally {
      setBusyMessage('');
    }
  };

  const handleResync = async () => {
    setBusyMessage('Re-syncing from DMS...');
    try {
      await domainsAPI.resync();
      const list = await loadDomains(false);
      if (selectedDomain && !list.find((d) => d.domain === selectedDomain)) {
        const first = list[0]?.domain || null;
        setSelectedDomain(first);
        if (first) {
          await loadMailboxes(first, false);
          await loadHealthStatus(first);
        }
      } else if (selectedDomain) {
        await loadMailboxes(selectedDomain, false);
      }
      showToast('DMS sync complete', 'success');
    } catch (err) {
      showToast(`Sync failed: ${err.message}`, 'error');
    } finally {
      setBusyMessage('');
    }
  };

  const handleLogout = async () => {
    try { await authAPI.logout(); } catch { /* ignore */ }
    setUser(null);
    setDomains([]);
    setMailboxes([]);
    setSelectedDomain(null);
    setHealthStatus(null);
  };

  const handleDelete = async () => {
    if (!deleteTarget) return;
    try {
      await mailboxesAPI.remove(deleteTarget);
      showToast(`Deleted ${deleteTarget}`, 'success');
      setDeleteTarget(null);
      await loadMailboxes(selectedDomain, false);
      await loadDomains(false);
    } catch (err) {
      showToast(`Delete failed: ${err.message}`, 'error');
    }
  };

  const handleMailboxCreated = async () => {
    setBusyMessage('Refreshing...');
    try {
      await loadDomains(false);
      await loadMailboxes(selectedDomain, true);
    } finally {
      setBusyMessage('');
    }
  };

  const handleQuotaApplied = async () => {
    setBusyMessage('Refreshing quotas...');
    try {
      await loadMailboxes(selectedDomain, true);
    } finally {
      setBusyMessage('');
    }
  };

  // Called by HealthModal after a fresh check completes — re-load the
  // persisted summary so the banner reflects the new state.
  const handleHealthChecked = async () => {
    if (selectedDomain) await loadHealthStatus(selectedDomain);
  };

  if (!bootChecked) {
    return <div className="min-h-screen flex items-center justify-center text-gray-400">Loading...</div>;
  }

  if (!user) {
    return (
      <>
        <Login onLogin={setUser} />
        {toast && <Toast {...toast} onClose={() => setToast(null)} />}
      </>
    );
  }

  return (
    <div className="min-h-screen">
      <header className="bg-white border-b border-gray-200 sticky top-0 z-10">
        <div className="max-w-7xl mx-auto px-6 py-4 flex items-center justify-between gap-4">
          <div className="min-w-0">
            <h1 className="text-xl font-bold text-gray-900">MailAdmin</h1>
            <p className="text-xs text-gray-500 truncate">
              {user.email} · <span className="font-medium">{user.role}</span>
            </p>
          </div>
          <div className="flex items-center gap-2 flex-wrap justify-end">
            <button onClick={() => setShowChangePw(true)} className="btn-secondary" title="Change my password">
              <FiUser className="w-4 h-4 mr-2" />
              My Password
            </button>
            {isSuperAdmin && (
              <>
                <button onClick={() => setShowBilling(true)} className="btn-secondary">
                  <FiDollarSign className="w-4 h-4 mr-2" />
                  Billing
                </button>
                <button onClick={() => setShowAudit(true)} className="btn-secondary">
                  <FiList className="w-4 h-4 mr-2" />
                  Audit Log
                </button>
                <button onClick={() => setShowAdmins(true)} className="btn-secondary">
                  <FiUsers className="w-4 h-4 mr-2" />
                  Admins
                </button>
                <button onClick={handleResync} className="btn-secondary">
                  <FiRefreshCw className="w-4 h-4 mr-2" />
                  DMS Resync
                </button>
              </>
            )}
            <button onClick={handleLogout} className="btn-ghost">
              <FiLogOut className="w-4 h-4 mr-2" />
              Logout
            </button>
          </div>
        </div>
      </header>

      <main className="max-w-7xl mx-auto px-6 py-6">
        <div className={`grid grid-cols-1 ${hideDomainList ? '' : 'lg:grid-cols-[320px_1fr]'} gap-6 items-start`}>
          {!hideDomainList && (
            <section className="card">
              <h2 className="text-base font-semibold text-gray-900">Domains on this node</h2>
              <p className="text-xs text-gray-500 mt-1 mb-4">
                {isSuperAdmin
                  ? 'Domains are discovered dynamically from DMS accounts.'
                  : 'Your assigned domains.'}
              </p>

              {domains.length === 0 ? (
                <p className="text-sm text-gray-400">No domains available.</p>
              ) : (
                <div className="flex flex-col gap-2">
                  {domains.map((d) => {
                    const active = d.domain === selectedDomain;
                    return (
                      <button
                        key={d.domain}
                        onClick={() => selectDomain(d.domain)}
                        className={`text-left p-3 rounded-lg border transition-colors ${
                          active
                            ? 'border-primary-500 bg-primary-50'
                            : 'border-gray-200 bg-white hover:border-gray-300'
                        }`}
                      >
                        <div className="font-semibold text-gray-900">{d.domain}</div>
                        <div className="text-xs text-gray-500 mt-0.5">
                          {d.active_mailboxes || 0} inboxes · {formatBytes(d.used_bytes)}
                        </div>
                        <div className="flex flex-wrap gap-1 mt-2">
                          <span className="pill">{d.current_node || d.node_name}</span>
                          <span className={d.status === 'active' ? 'pill-success' : 'pill'}>
                            {d.status}
                          </span>
                        </div>
                      </button>
                    );
                  })}
                </div>
              )}
            </section>
          )}

          <section className="card relative">
            {/* Health banner (shows only when last check found problems) */}
            <HealthBanner status={healthStatus} onOpen={() => setShowHealth(true)} />

            <div className="flex items-start justify-between gap-4 mb-5 flex-wrap">
              <div>
                <h2 className="text-base font-semibold text-gray-900">
                  {selectedDomain || 'Mailboxes'}
                </h2>
                <p className="text-xs text-gray-500 mt-1">
                  Create/delete mailboxes, reset passwords, edit rules. Quotas are refreshed when you open a domain.
                </p>
              </div>
              <div className="flex flex-row flex-wrap gap-2">
                <button
                  onClick={() => setShowHealth(true)}
                  disabled={!selectedDomain}
                  className="btn-secondary"
                  title="Run DNS, DMS and TLS cert checks for this domain"
                >
                  <FiActivity className="w-4 h-4 mr-2" />
                  Check health
                </button>
                {isSuperAdmin && (
                  <button
                    onClick={() => setShowDomainQuota(true)}
                    disabled={!selectedDomain || mailboxes.length === 0}
                    className="btn-secondary"
                    title="Set quota for all mailboxes in this domain"
                  >
                    <FiHardDrive className="w-4 h-4 mr-2" />
                    Set quota
                  </button>
                )}
                <button
                  onClick={() => setShowNew(true)}
                  disabled={!selectedDomain}
                  className="btn-primary"
                >
                  <FiPlus className="w-4 h-4 mr-2" />
                  New mailbox
                </button>
              </div>
            </div>

            {mailboxes.length === 0 ? (
              <div className="text-center py-12 bg-gray-50 border-2 border-dashed border-gray-300 rounded-lg">
                <FiInbox className="w-12 h-12 text-gray-400 mx-auto mb-3" />
                <p className="text-gray-600 font-medium">No mailboxes for this domain</p>
                <p className="text-sm text-gray-500 mt-1">
                  {selectedDomain ? 'Click "New mailbox" to create the first one.' : 'Select a domain first.'}
                </p>
              </div>
            ) : (
              <div className="overflow-x-auto">
                <table className="w-full text-sm">
                  <thead>
                    <tr className="text-left text-xs uppercase tracking-wide text-gray-500 border-b border-gray-200">
                      <th className="py-3 pr-4 font-semibold">Email</th>
                      <th className="py-3 pr-4 font-semibold">Status</th>
                      <th className="py-3 pr-4 font-semibold">Usage</th>
                      <th className="py-3 pr-4 font-semibold whitespace-nowrap">Updated</th>
                      <th className="py-3 pr-2 font-semibold">Actions</th>
                    </tr>
                  </thead>
                  <tbody className="divide-y divide-gray-100">
                    {mailboxes.map((m) => (
                      <tr key={m.email_address} className="align-top hover:bg-gray-50">
                        <td className="py-3 pr-4">
                          <div className="font-semibold text-gray-900">{m.email_address}</div>
                          <div className="text-xs text-gray-500">{m.node_name}</div>
                        </td>
                        <td className="py-3 pr-4">
                          <span className={m.status === 'active' ? 'pill-success' : 'pill'}>
                            {m.status}
                          </span>
                        </td>
                        <td className="py-3 pr-4"><UsageBar mailbox={m} /></td>
                        <td className="py-3 pr-4 text-xs text-gray-500 whitespace-nowrap">
                          {new Date(m.updated_at).toLocaleString()}
                        </td>
                        <td className="py-3 pr-2">
                          <div className="flex flex-row flex-nowrap items-center gap-2">
                            <button
                              onClick={() => setSettingsTarget({ email: m.email_address, tab: 'fwd' })}
                              className="btn-secondary"
                              title="Forwarding & Auto-Reply"
                            >
                              <FiSettings className="w-3.5 h-3.5 mr-1.5" />
                              Settings
                            </button>
                            <button
                              onClick={() => setPwTarget(m.email_address)}
                              className="btn-secondary"
                              title="Reset password"
                            >
                              <FiKey className="w-3.5 h-3.5 mr-1.5" />
                              Password
                            </button>
                            <button
                              onClick={() => setDeleteTarget(m.email_address)}
                              className="btn-danger"
                              title="Delete mailbox"
                            >
                              <FiTrash2 className="w-3.5 h-3.5 mr-1.5" />
                              Delete
                            </button>
                          </div>
                        </td>
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>
            )}
          </section>
        </div>
      </main>

      <MailboxSettingsModal
        open={!!settingsTarget}
        email={settingsTarget?.email}
        initialTab={settingsTarget?.tab}
        onClose={() => setSettingsTarget(null)}
        onToast={showToast}
      />
      <NewMailboxModal
        open={showNew}
        domain={selectedDomain}
        onClose={() => setShowNew(false)}
        onCreated={handleMailboxCreated}
        onToast={showToast}
      />
      <PasswordResetModal
        open={!!pwTarget}
        email={pwTarget}
        onClose={() => setPwTarget(null)}
        onToast={showToast}
      />
      <ConfirmDialog
        open={!!deleteTarget}
        title="Delete mailbox"
        message={
          deleteTarget
            ? `Delete ${deleteTarget} from DMS? This cannot be undone.`
            : ''
        }
        confirmLabel="Delete"
        danger
        onConfirm={handleDelete}
        onClose={() => setDeleteTarget(null)}
      />
      {isSuperAdmin && (
        <AuditLogModal
          open={showAudit}
          onClose={() => setShowAudit(false)}
          onToast={showToast}
        />
      )}
      {isSuperAdmin && (
        <AdminUsersModal
          open={showAdmins}
          currentUser={user}
          onClose={() => setShowAdmins(false)}
          onToast={showToast}
        />
      )}
      {isSuperAdmin && (
        <DomainQuotaModal
          open={showDomainQuota}
          domain={selectedDomain}
          mailboxes={mailboxes}
          onClose={() => setShowDomainQuota(false)}
          onApplied={handleQuotaApplied}
          onToast={showToast}
        />
      )}
      {isSuperAdmin && (
        <BillingModal
          open={showBilling}
          domains={domains}
          onClose={() => setShowBilling(false)}
          onToast={showToast}
        />
      )}
      <HealthModal
        open={showHealth}
        domain={selectedDomain}
        onClose={() => setShowHealth(false)}
        onCheckedReport={handleHealthChecked}
        onToast={showToast}
      />
      <ChangeMyPasswordModal
        open={showChangePw}
        onClose={() => setShowChangePw(false)}
        onToast={showToast}
      />

      {busyMessage && <LoadingOverlay message={busyMessage} fullscreen />}
      {toast && <Toast {...toast} onClose={() => setToast(null)} />}
    </div>
  );
}

export default App;
