'use client';

import { useEffect, useMemo, useState } from 'react';

type UserRecord = {
  id: string;
  name: string;
  email: string;
  status: 'invited' | 'active' | 'inactive' | 'suspended';
  roleId: string | null;
  roleName: string;
  createdAt: string;
  updatedAt: string;
  lastLoginAt: string | null;
  emailVerifiedAt: string | null;
};

type RoleOption = {
  id: string;
  name: string;
};

type Props = {
  initialUsers: UserRecord[];
  initialTotal: number;
  initialPage: number;
  initialPageSize: number;
  initialTotalPages: number;
  availableRoles: RoleOption[];
};

type PanelMode = 'create' | 'edit' | null;

function formatLastSeen(value: string | null, status: UserRecord['status']) {
  if (status === 'invited') return 'Pending invite';
  if (!value) return 'Never';

  const diffMs = Date.now() - new Date(value).getTime();
  const minutes = Math.max(1, Math.floor(diffMs / 60000));
  if (minutes < 60) return 'Just now';
  const hours = Math.floor(minutes / 60);
  if (hours < 24) return `${hours} hour${hours === 1 ? '' : 's'} ago`;
  const days = Math.floor(hours / 24);
  return `${days} day${days === 1 ? '' : 's'} ago`;
}

function formatStatusLabel(status: UserRecord['status']) {
  switch (status) {
    case 'active':
      return 'Active';
    case 'invited':
      return 'Invited';
    case 'inactive':
      return 'Inactive';
    case 'suspended':
      return 'Suspended';
  }
}

function getStatusTone(status: UserRecord['status']) {
  switch (status) {
    case 'active':
      return 'success';
    case 'invited':
      return 'warning';
    case 'suspended':
      return 'error';
    case 'inactive':
      return 'muted';
  }
}

function getRoleTone(roleName: string) {
  const normalized = roleName.toLowerCase();
  if (normalized.includes('admin')) return 'admin';
  if (normalized.includes('editor')) return 'editor';
  return 'agent';
}

function initials(name: string) {
  return name
    .split(/\s+/)
    .slice(0, 2)
    .map((part) => part[0]?.toUpperCase() || '')
    .join('');
}

const roleDescriptions: Record<string, string> = {
  Admin: 'Full system access, including billing, user management, and API settings.',
  Editor: 'Manage broadcasts and message templates, but cannot change system settings.',
  Agent: 'Limited to handling conversations, contacts, and operational response flow.',
};

export function UsersManagementBoard({
  initialUsers,
  initialTotal,
  initialPage,
  initialPageSize,
  initialTotalPages,
  availableRoles,
}: Props) {
  const [users, setUsers] = useState(initialUsers);
  const [total, setTotal] = useState(initialTotal);
  const [page, setPage] = useState(initialPage);
  const [pageSize] = useState(initialPageSize);
  const [totalPages, setTotalPages] = useState(initialTotalPages);
  const [search, setSearch] = useState('');
  const [debouncedSearch, setDebouncedSearch] = useState('');
  const [statusFilter, setStatusFilter] = useState('all');
  const [roleFilter, setRoleFilter] = useState('all');
  const [showFilters, setShowFilters] = useState(false);
  const [panelMode, setPanelMode] = useState<PanelMode>(null);
  const [editingUserId, setEditingUserId] = useState<string | null>(null);
  const [feedback, setFeedback] = useState('');
  const [inviteName, setInviteName] = useState('');
  const [inviteEmail, setInviteEmail] = useState('');
  const [inviteRoleId, setInviteRoleId] = useState(availableRoles[0]?.id || '');
  const [editName, setEditName] = useState('');
  const [editEmail, setEditEmail] = useState('');
  const [editRoleId, setEditRoleId] = useState('');
  const [editStatus, setEditStatus] = useState<UserRecord['status']>('active');
  const [isSaving, setIsSaving] = useState(false);
  const [isLoading, setIsLoading] = useState(false);

  const editingUser = useMemo(
    () => users.find((user) => user.id === editingUserId) ?? null,
    [editingUserId, users],
  );

  const stats = useMemo(() => {
    const totalUsers = total;
    const pendingInvites = users.filter((user) => user.status === 'invited').length;
    const activeRecently = users.filter((user) => {
      if (!user.lastLoginAt) return false;
      return Date.now() - new Date(user.lastLoginAt).getTime() <= 24 * 60 * 60 * 1000;
    }).length;
    return { totalUsers, pendingInvites, activeRecently };
  }, [total, users]);

  const visibleRoles = useMemo(() => {
    const base = availableRoles.map((role) => role.name);
    return base.slice(0, 3);
  }, [availableRoles]);

  useEffect(() => {
    const timeout = window.setTimeout(() => {
      setDebouncedSearch(search.trim());
      setPage(1);
    }, 250);
    return () => window.clearTimeout(timeout);
  }, [search]);

  useEffect(() => {
    const controller = new AbortController();

    async function loadUsers() {
      try {
        setIsLoading(true);
        const params = new URLSearchParams();
        params.set('page', String(page));
        params.set('limit', String(pageSize));
        if (debouncedSearch) params.set('search', debouncedSearch);
        if (statusFilter !== 'all') params.set('status', statusFilter);
        if (roleFilter !== 'all') params.set('roleId', roleFilter);

        const response = await fetch(`/api/users?${params.toString()}`, {
          signal: controller.signal,
          cache: 'no-store',
        });
        const payload = await response.json();
        if (!response.ok) {
          setFeedback(payload.message || 'Failed to load users');
          return;
        }

        setUsers(payload.items);
        setTotal(payload.total);
        setTotalPages(payload.totalPages);
      } catch (error) {
        if ((error as Error).name !== 'AbortError') {
          setFeedback('Failed to load users');
        }
      } finally {
        setIsLoading(false);
      }
    }

    loadUsers();
    return () => controller.abort();
  }, [debouncedSearch, page, pageSize, roleFilter, statusFilter]);

  function closePanel() {
    setPanelMode(null);
    setEditingUserId(null);
  }

  function openCreatePanel() {
    setPanelMode('create');
    setEditingUserId(null);
    setFeedback('');
  }

  function beginEdit(user: UserRecord) {
    setPanelMode('edit');
    setEditingUserId(user.id);
    setEditName(user.name);
    setEditEmail(user.email);
    setEditRoleId(user.roleId || '');
    setEditStatus(user.status);
    setFeedback('');
  }

  async function submitInvite() {
    setIsSaving(true);
    try {
      const response = await fetch('/api/users', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          name: inviteName,
          email: inviteEmail,
          roleId: inviteRoleId || undefined,
        }),
      });
      const payload = await response.json();
      if (!response.ok) {
        setFeedback(payload.message || 'Failed to invite user');
        return;
      }

      setFeedback(
        payload.emailSent
          ? `Invitation sent to ${payload.email}.`
          : `User invited, but email was not sent. Activation link: ${payload.invitationUrl}`,
      );
      setInviteName('');
      setInviteEmail('');
      setInviteRoleId(availableRoles[0]?.id || '');
      closePanel();
      setPage(1);
      setDebouncedSearch('');
      setSearch('');
    } finally {
      setIsSaving(false);
    }
  }

  async function submitEdit() {
    if (!editingUser) return;
    setIsSaving(true);
    try {
      const response = await fetch(`/api/users/${editingUser.id}`, {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          name: editName,
          email: editEmail,
          roleId: editRoleId || undefined,
          status: editStatus,
        }),
      });
      const payload = await response.json();
      if (!response.ok) {
        setFeedback(payload.message || 'Failed to update user');
        return;
      }

      setUsers((current) =>
        current.map((user) =>
          user.id === payload.id
            ? {
                ...user,
                name: payload.name,
                email: payload.email,
                status: payload.status,
                roleId: payload.roleId,
                roleName: payload.roleName,
                lastLoginAt: payload.lastLoginAt,
                emailVerifiedAt: payload.emailVerifiedAt,
              }
            : user,
        ),
      );
      setFeedback(`User ${payload.email} updated.`);
      closePanel();
    } finally {
      setIsSaving(false);
    }
  }

  async function resendInvite(user: UserRecord) {
    setIsSaving(true);
    try {
      const response = await fetch('/api/users', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          name: user.name,
          email: user.email,
          roleId: user.roleId || undefined,
        }),
      });
      const payload = await response.json();
      if (!response.ok) {
        setFeedback(payload.message || 'Failed to resend invite');
        return;
      }

      setFeedback(
        payload.emailSent
          ? `Invitation resent to ${payload.email}.`
          : `Invite refreshed, but email was not sent. Activation link: ${payload.invitationUrl}`,
      );
    } finally {
      setIsSaving(false);
    }
  }

  function resetFilters() {
    setSearch('');
    setDebouncedSearch('');
    setStatusFilter('all');
    setRoleFilter('all');
    setPage(1);
  }

  function exportUsers() {
    const params = new URLSearchParams();
    if (debouncedSearch) params.set('search', debouncedSearch);
    if (statusFilter !== 'all') params.set('status', statusFilter);
    if (roleFilter !== 'all') params.set('roleId', roleFilter);
    window.location.href = `/api/users/export${params.size ? `?${params.toString()}` : ''}`;
  }

  return (
    <section className="users-board">
      <section className="page-header split users-page-header">
        <div>
          <p className="page-eyebrow">Users</p>
          <h1 className="page-heading">User Management</h1>
          <p className="page-copy">Manage team access levels, roles, and security permissions.</p>
        </div>
        <div className="header-actions">
          <button type="button" className="users-hero-button" onClick={openCreatePanel}>
            <span className="material-symbols-outlined">person_add</span>
            Create User
          </button>
        </div>
      </section>

      <section className="users-stats-grid">
        <article className="users-stat-card">
          <div>
            <p className="users-stat-label">Total Users</p>
            <h3>{stats.totalUsers}</h3>
            <p className="users-stat-copy">
              <span className="material-symbols-outlined">trending_up</span>
              Directory accounts
            </p>
          </div>
          <div className="users-stat-icon tone-primary">
            <span className="material-symbols-outlined">group</span>
          </div>
        </article>

        <article className="users-stat-card">
          <div>
            <p className="users-stat-label">Pending Invites</p>
            <h3>{stats.pendingInvites}</h3>
            <p className="users-stat-copy is-warning">
              <span className="material-symbols-outlined">schedule</span>
              Awaiting response
            </p>
          </div>
          <div className="users-stat-icon tone-secondary">
            <span className="material-symbols-outlined">mail</span>
          </div>
        </article>

        <article className="users-stat-card is-accent">
          <div className="users-stat-content">
            <p className="users-stat-label">Active Sessions</p>
            <h3>{stats.activeRecently}</h3>
            <p className="users-stat-copy">Current real-time activity</p>
          </div>
          <div className="users-stat-icon tone-contrast">
            <span className="material-symbols-outlined">bolt</span>
          </div>
          <div className="users-stat-glow" />
        </article>
      </section>

      {panelMode === 'create' ? (
        <section className="users-panel-layout">
          <div className="users-create-main">
            <article className="users-form-card create">
              <div className="users-form-head create">
                <div>
                  <p className="card-kicker">Settings / Team Management</p>
                  <h2>Add New Team Member</h2>
                  <p>Invite a new administrator or support agent to your business dashboard.</p>
                </div>
              </div>

              <div className="users-create-section">
                <h3>
                  <span className="material-symbols-outlined">person_add</span>
                  Profile Information
                </h3>
                <div className="users-form-grid">
                  <label className="users-form-field">
                    <span>Full Name</span>
                    <input value={inviteName} onChange={(event) => setInviteName(event.target.value)} placeholder="e.g. Sarah Jenkins" />
                  </label>
                  <label className="users-form-field">
                    <span>Email Address</span>
                    <input value={inviteEmail} onChange={(event) => setInviteEmail(event.target.value)} placeholder="sarah.j@enterprise.com" />
                  </label>
                  <label className="users-form-field">
                    <span>Phone Number (Optional)</span>
                    <input placeholder="+1 (555) 000-0000" disabled />
                  </label>
                  <label className="users-form-field">
                    <span>Role Selection</span>
                    <select value={inviteRoleId} onChange={(event) => setInviteRoleId(event.target.value)}>
                      {availableRoles.map((role) => (
                        <option key={role.id} value={role.id}>
                          {role.name}
                        </option>
                      ))}
                    </select>
                  </label>
                </div>
              </div>

              <div className="users-footer-actions">
                <button type="button" className="secondary-button" onClick={closePanel}>
                  Cancel
                </button>
                <button type="button" className="users-hero-button" onClick={submitInvite} disabled={isSaving}>
                  <span className="material-symbols-outlined">send</span>
                  {isSaving ? 'Creating...' : 'Create User'}
                </button>
              </div>
            </article>
          </div>

          <aside className="users-create-side">
            <article className="users-summary-card">
              <h4>Summary</h4>
              <div className="users-summary-list">
                <div>
                  <span>Role</span>
                  <strong>
                    {availableRoles.find((role) => role.id === inviteRoleId)?.name || 'Support Agent'}
                  </strong>
                </div>
                <div>
                  <span>Status</span>
                  <strong>Draft Invitation</strong>
                </div>
                <p>
                  Inviting this user will send a secure email link so they can verify their address and
                  set their own password.
                </p>
              </div>
            </article>

            <article className="users-illustration-card">
              <div className="users-illustration-art" />
              <div className="users-illustration-copy">
                <h5>Secure Onboarding</h5>
                <p>Users receive a time-limited invitation link to create their own credentials.</p>
              </div>
            </article>
          </aside>
        </section>
      ) : null}

      {panelMode === 'edit' && editingUser ? (
        <section className="users-edit-layout">
          <aside className="users-edit-side">
            <article className="users-profile-card">
              <div className="users-profile-avatar">{initials(editingUser.name)}</div>
              <h3>{editingUser.name}</h3>
              <p>{editingUser.email}</p>
              <div className="users-profile-meta">
                <div>
                  <div>
                    <p>Status</p>
                    <strong className={`tone-${getStatusTone(editingUser.status)}`}>
                      {formatStatusLabel(editingUser.status)}
                    </strong>
                  </div>
                </div>
                <div>
                  <p>Last Active</p>
                  <strong>{formatLastSeen(editingUser.lastLoginAt, editingUser.status)}</strong>
                </div>
              </div>
            </article>

            <article className="users-security-card">
              <h4>Security Actions</h4>
              <button
                type="button"
                className="users-toolbar-button full"
                onClick={() => resendInvite(editingUser)}
                disabled={isSaving}
              >
                <span className="material-symbols-outlined">lock_reset</span>
                Send Password Reset Link
              </button>
            </article>
          </aside>

          <div className="users-edit-main">
            <article className="users-form-card edit">
              <div className="users-form-head edit">
                <div>
                  <p className="card-kicker">Edit User</p>
                  <h2>Update user access and account status</h2>
                  <p>Change display details, role assignment, and lifecycle state without leaving the directory.</p>
                </div>
                <span className={`users-panel-badge tone-${getStatusTone(editingUser.status)}`}>
                  {formatStatusLabel(editingUser.status)}
                </span>
              </div>

              <div className="users-form-grid">
                <label className="users-form-field">
                  <span>Full Name</span>
                  <input value={editName} onChange={(event) => setEditName(event.target.value)} />
                </label>
                <label className="users-form-field">
                  <span>Email Address</span>
                  <input value={editEmail} onChange={(event) => setEditEmail(event.target.value)} />
                </label>
                <label className="users-form-field">
                  <span>Role</span>
                  <select value={editRoleId} onChange={(event) => setEditRoleId(event.target.value)}>
                    <option value="">Unassigned</option>
                    {availableRoles.map((role) => (
                      <option key={role.id} value={role.id}>
                        {role.name}
                      </option>
                    ))}
                  </select>
                </label>
                <label className="users-form-field">
                  <span>Status</span>
                  <select value={editStatus} onChange={(event) => setEditStatus(event.target.value as UserRecord['status'])}>
                    <option value="invited">Invited</option>
                    <option value="active">Active</option>
                    <option value="inactive">Inactive</option>
                    <option value="suspended">Suspended</option>
                  </select>
                </label>
              </div>

              <div className="users-edit-meta">
                <div>
                  <strong>{editingUser.emailVerifiedAt ? 'Verified' : 'Pending Verification'}</strong>
                  <span>Email verification</span>
                </div>
                <div>
                  <strong>{formatLastSeen(editingUser.lastLoginAt, editingUser.status)}</strong>
                  <span>Last activity</span>
                </div>
              </div>

              <div className="users-footer-actions">
                <button type="button" className="secondary-button" onClick={closePanel}>
                  Cancel
                </button>
                <button type="button" className="users-hero-button" onClick={submitEdit} disabled={isSaving}>
                  <span className="material-symbols-outlined">save</span>
                  {isSaving ? 'Saving...' : 'Save Changes'}
                </button>
              </div>
            </article>

            <article className="users-danger-card">
              <div className="users-danger-icon">
                <span className="material-symbols-outlined">warning</span>
              </div>
              <div>
                <h4>Danger Zone</h4>
                <p>Deleting this user is not enabled yet. For now, use `Suspended` status to revoke access safely.</p>
                <button type="button" disabled>
                  Delete User
                </button>
              </div>
            </article>
          </div>
        </section>
      ) : null}

      {feedback ? <p className="users-feedback">{feedback}</p> : null}

      <section className="users-table-shell">
        <div className="users-table-toolbar">
          <h4>Team Members</h4>
          <div className="users-toolbar-actions">
            <button type="button" className="users-toolbar-button large" onClick={() => setShowFilters((current) => !current)}>
              <span className="material-symbols-outlined">filter_list</span>
              Filter
            </button>
            <button type="button" className="users-toolbar-button large" onClick={exportUsers}>
              <span className="material-symbols-outlined">download</span>
              Export
            </button>
          </div>
        </div>

        {showFilters ? (
          <div className="users-filters-panel">
            <label className="users-filter-field">
              <span>Search team members</span>
              <input value={search} onChange={(event) => setSearch(event.target.value)} placeholder="Search name or email..." />
            </label>
            <label className="users-filter-field">
              <span>Status</span>
              <select value={statusFilter} onChange={(event) => {
                setStatusFilter(event.target.value);
                setPage(1);
              }}>
                <option value="all">All Statuses</option>
                <option value="invited">Invited</option>
                <option value="active">Active</option>
                <option value="inactive">Inactive</option>
                <option value="suspended">Suspended</option>
              </select>
            </label>
            <label className="users-filter-field">
              <span>Role</span>
              <select value={roleFilter} onChange={(event) => {
                setRoleFilter(event.target.value);
                setPage(1);
              }}>
                <option value="all">All Roles</option>
                {availableRoles.map((role) => (
                  <option key={role.id} value={role.id}>
                    {role.name}
                  </option>
                ))}
              </select>
            </label>
            <div className="users-filter-actions">
              <button type="button" className="secondary-button" onClick={resetFilters}>
                Reset
              </button>
            </div>
          </div>
        ) : null}

        <div className="users-table-wrap">
          <table className="users-table">
            <thead>
              <tr>
                <th>Name / Email</th>
                <th>Role</th>
                <th>Last Active</th>
                <th>Status</th>
                <th className="align-right">Actions</th>
              </tr>
            </thead>
            <tbody>
              {users.map((user) => (
                <tr key={user.id}>
                  <td>
                    <div className="users-identity">
                      <div className={`users-avatar tone-${getRoleTone(user.roleName)}`}>{initials(user.name)}</div>
                      <div>
                        <p>{user.name}</p>
                        <span>{user.email}</span>
                      </div>
                    </div>
                  </td>
                  <td>
                    <span className={`users-role-pill tone-${getRoleTone(user.roleName)}`}>
                      {user.roleName.toUpperCase()}
                    </span>
                  </td>
                  <td className="users-muted">{formatLastSeen(user.lastLoginAt, user.status)}</td>
                  <td>
                    <div className="users-status">
                      <span className={`users-status-dot tone-${getStatusTone(user.status)}`} />
                      <span>{formatStatusLabel(user.status)}</span>
                    </div>
                  </td>
                  <td>
                    <div className="users-actions">
                      {user.status === 'invited' ? (
                        <button type="button" onClick={() => resendInvite(user)} title="Resend Invite">
                          <span className="material-symbols-outlined">mail</span>
                        </button>
                      ) : null}
                      <button type="button" onClick={() => beginEdit(user)} title="Edit User">
                        <span className="material-symbols-outlined">edit</span>
                      </button>
                    </div>
                  </td>
                </tr>
              ))}
              {users.length === 0 ? (
                <tr>
                  <td colSpan={5} className="users-empty-state">
                    No users matched the current filters.
                  </td>
                </tr>
              ) : null}
            </tbody>
          </table>
        </div>

        <div className="users-pagination">
          <p>
            Showing {users.length === 0 ? 0 : (page - 1) * pageSize + 1} to {(page - 1) * pageSize + users.length} of {total} team members
          </p>
          <div className="users-pagination-buttons">
            <button type="button" onClick={() => setPage((current) => Math.max(1, current - 1))} disabled={page <= 1}>
              <span className="material-symbols-outlined">chevron_left</span>
            </button>
            {Array.from({ length: totalPages }, (_, index) => index + 1)
              .slice(Math.max(0, page - 2), Math.max(0, page - 2) + 3)
              .map((pageNumber) => (
                <button
                  key={pageNumber}
                  type="button"
                  className={pageNumber === page ? 'is-active' : ''}
                  onClick={() => setPage(pageNumber)}
                >
                  {pageNumber}
                </button>
              ))}
            <button type="button" onClick={() => setPage((current) => Math.min(totalPages, current + 1))} disabled={page >= totalPages}>
              <span className="material-symbols-outlined">chevron_right</span>
            </button>
          </div>
        </div>
        {isLoading ? <div className="users-loading-bar" /> : null}
      </section>

      <section className="users-role-overview">
        <div>
          <h5>Role Permissions</h5>
          <p>Quick overview of what each team member can access across the WhatsApp Business platform.</p>
        </div>
        <div className="users-role-cards">
          {visibleRoles.map((roleName) => (
            <article key={roleName} className="users-role-card">
              <div className={`users-role-card-head tone-${getRoleTone(roleName)}`}>
                <span className="material-symbols-outlined">
                  {getRoleTone(roleName) === 'admin'
                    ? 'verified_user'
                    : getRoleTone(roleName) === 'editor'
                      ? 'edit_note'
                      : 'support_agent'}
                </span>
                <span>{roleName.toUpperCase()}</span>
              </div>
              <p>{roleDescriptions[roleName] || 'Operational access based on the assigned role matrix.'}</p>
            </article>
          ))}
        </div>
      </section>
    </section>
  );
}
