import { useState } from 'react';
import { useAuthStore } from '../../auth/auth-store';
import { useAuditLog, type AuditLogParams } from '../../api/queries/admin/audit';
import layout from '../../styles/AdminLayout.module.css';
import styles from './AuditLogPage.module.css';

function defaultFrom(): string {
  const d = new Date();
  d.setDate(d.getDate() - 7);
  return d.toISOString().slice(0, 10);
}

function defaultTo(): string {
  return new Date().toISOString().slice(0, 10);
}

export function AuditLogPage() {
  const roles = useAuthStore((s) => s.roles);

  if (!roles.includes('ADMIN')) {
    return (
      <div className={layout.page}>
        <div className={layout.accessDenied}>
          Access Denied -- this page requires the ADMIN role.
        </div>
      </div>
    );
  }

  return <AuditLogContent />;
}

function AuditLogContent() {
  const [from, setFrom] = useState(defaultFrom);
  const [to, setTo] = useState(defaultTo);
  const [username, setUsername] = useState('');
  const [category, setCategory] = useState('');
  const [search, setSearch] = useState('');
  const [page, setPage] = useState(0);
  const [expandedRow, setExpandedRow] = useState<number | null>(null);
  const pageSize = 25;

  const params: AuditLogParams = {
    from: from || undefined,
    to: to || undefined,
    username: username || undefined,
    category: category || undefined,
    search: search || undefined,
    page,
    size: pageSize,
  };

  const audit = useAuditLog(params);
  const data = audit.data;
  const totalPages = data?.totalPages ?? 0;
  const showingFrom = data && data.totalCount > 0 ? page * pageSize + 1 : 0;
  const showingTo = data ? Math.min((page + 1) * pageSize, data.totalCount) : 0;

  return (
    <div className={layout.page}>
      {/* Header */}
      <div className={layout.panelHeader}>
        <div>
          <div className={layout.panelTitle}>Audit Log</div>
          <div className={layout.panelSubtitle}>
            {data
              ? `${data.totalCount.toLocaleString()} events`
              : 'Loading...'}
          </div>
        </div>
      </div>

      {/* Filter bar */}
      <div className={styles.filterBar}>
        <div className={styles.filterGroup}>
          <label className={styles.filterLabel}>From</label>
          <input
            type="date"
            className={styles.filterInput}
            value={from}
            onChange={(e) => { setFrom(e.target.value); setPage(0); }}
          />
        </div>
        <div className={styles.filterGroup}>
          <label className={styles.filterLabel}>To</label>
          <input
            type="date"
            className={styles.filterInput}
            value={to}
            onChange={(e) => { setTo(e.target.value); setPage(0); }}
          />
        </div>
        <div className={styles.filterGroup}>
          <label className={styles.filterLabel}>User</label>
          <input
            type="text"
            className={styles.filterInput}
            placeholder="Username..."
            value={username}
            onChange={(e) => { setUsername(e.target.value); setPage(0); }}
          />
        </div>
        <div className={styles.filterGroup}>
          <label className={styles.filterLabel}>Category</label>
          <select
            className={styles.filterSelect}
            value={category}
            onChange={(e) => { setCategory(e.target.value); setPage(0); }}
          >
            <option value="">All</option>
            <option value="INFRA">INFRA</option>
            <option value="AUTH">AUTH</option>
            <option value="USER_MGMT">USER_MGMT</option>
            <option value="CONFIG">CONFIG</option>
          </select>
        </div>
        <div className={`${styles.filterGroup} ${styles.filterGroupGrow}`}>
          <label className={styles.filterLabel}>Search</label>
          <input
            type="text"
            className={styles.filterInput}
            placeholder="Search actions, targets..."
            value={search}
            onChange={(e) => { setSearch(e.target.value); setPage(0); }}
          />
        </div>
      </div>

      {/* Table area */}
      <div className={styles.tableArea}>
        {audit.isLoading ? (
          <div className={layout.loading}>Loading...</div>
        ) : !data || data.items.length === 0 ? (
          <div className={styles.emptyState}>
            No audit events found for the selected filters.
          </div>
        ) : (
          <table className={styles.table}>
            <thead>
              <tr>
                <th className={styles.thTimestamp}>Timestamp</th>
                <th>User</th>
                <th>Category</th>
                <th>Action</th>
                <th>Target</th>
                <th className={styles.thResult}>Result</th>
              </tr>
            </thead>
            <tbody>
              {data.items.map((event) => (
                <EventRow
                  key={event.id}
                  event={event}
                  isExpanded={expandedRow === event.id}
                  onToggle={() =>
                    setExpandedRow((prev) => (prev === event.id ? null : event.id))
                  }
                />
              ))}
            </tbody>
          </table>
        )}
      </div>

      {/* Pagination */}
      {data && data.totalCount > 0 && (
        <div className={styles.pagination}>
          <button
            type="button"
            className={styles.pageBtn}
            disabled={page === 0}
            onClick={() => setPage((p) => p - 1)}
          >
            Previous
          </button>
          <span className={styles.pageInfo}>
            {showingFrom}--{showingTo} of {data.totalCount.toLocaleString()}
          </span>
          <button
            type="button"
            className={styles.pageBtn}
            disabled={page >= totalPages - 1}
            onClick={() => setPage((p) => p + 1)}
          >
            Next
          </button>
        </div>
      )}
    </div>
  );
}

function EventRow({
  event,
  isExpanded,
  onToggle,
}: {
  event: {
    id: number;
    timestamp: string;
    username: string;
    category: string;
    action: string;
    target: string;
    result: string;
    detail: Record<string, unknown>;
    ipAddress: string;
    userAgent: string;
  };
  isExpanded: boolean;
  onToggle: () => void;
}) {
  return (
    <>
      <tr
        className={`${styles.eventRow} ${isExpanded ? styles.eventRowExpanded : ''}`}
        onClick={onToggle}
      >
        <td className={styles.cellTimestamp}>{formatTimestamp(event.timestamp)}</td>
        <td className={styles.cellUser}>{event.username}</td>
        <td>
          <span className={styles.categoryBadge}>{event.category}</span>
        </td>
        <td>{event.action}</td>
        <td className={styles.cellTarget}>{event.target}</td>
        <td>
          <span
            className={`${styles.resultBadge} ${
              event.result === 'SUCCESS' ? styles.resultSuccess : styles.resultFailure
            }`}
          >
            {event.result}
          </span>
        </td>
      </tr>
      {isExpanded && (
        <tr className={styles.detailRow}>
          <td colSpan={6}>
            <div className={styles.detailContent}>
              <div className={styles.detailMeta}>
                <div className={styles.detailField}>
                  <span className={styles.detailLabel}>IP Address</span>
                  <span className={styles.detailValue}>{event.ipAddress}</span>
                </div>
                <div className={styles.detailField}>
                  <span className={styles.detailLabel}>User Agent</span>
                  <span className={styles.detailValue}>{event.userAgent}</span>
                </div>
              </div>
              {event.detail && Object.keys(event.detail).length > 0 && (
                <pre className={styles.detailJson}>
                  {JSON.stringify(event.detail, null, 2)}
                </pre>
              )}
            </div>
          </td>
        </tr>
      )}
    </>
  );
}

function formatTimestamp(iso: string): string {
  try {
    const d = new Date(iso);
    return d.toLocaleString(undefined, {
      year: 'numeric',
      month: '2-digit',
      day: '2-digit',
      hour: '2-digit',
      minute: '2-digit',
      second: '2-digit',
    });
  } catch {
    return iso;
  }
}
