"use client";

import { useEffect, useState, useCallback } from "react";
import { Permission } from "../../auth-context";
import { api } from "../../api";
import { Header } from "../../components/Header";
import { useRequireAuth } from "../../hooks/useRequireAuth";
import { components } from "../../generated/api";
import constants from "../../../../shared/constants.json";
import {
  layoutStyles,
  cardStyles,
  tableStyles,
  paginationStyles,
  formStyles,
  buttonStyles,
  badgeStyles,
  utilityStyles,
} from "../../styles/shared";

const { READY, SPENT, REVOKED } = constants.inviteStatuses;

// Use generated types from OpenAPI schema
type _InviteRecord = components["schemas"]["InviteResponse"];
type PaginatedInvites = components["schemas"]["PaginatedResponse_InviteResponse_"];
type UserOption = components["schemas"]["AdminUserResponse"];

export default function AdminInvitesPage() {
  const [data, setData] = useState<PaginatedInvites | null>(null);
  const [error, setError] = useState<string | null>(null);
  const [page, setPage] = useState(1);
  const [statusFilter, setStatusFilter] = useState<string>("");
  const [isCreating, setIsCreating] = useState(false);
  const [newGodfatherId, setNewGodfatherId] = useState("");
  const [createError, setCreateError] = useState<string | null>(null);
  const [users, setUsers] = useState<UserOption[]>([]);
  const { user, isLoading, isAuthorized } = useRequireAuth({
    requiredPermission: Permission.MANAGE_INVITES,
    fallbackRedirect: "/",
  });

  const fetchUsers = useCallback(async () => {
    try {
      const data = await api.get<UserOption[]>("/api/admin/users");
      setUsers(data);
    } catch (err) {
      console.error("Failed to fetch users:", err);
    }
  }, []);

  const fetchInvites = useCallback(async (page: number, status: string) => {
    setError(null);
    try {
      let url = `/api/admin/invites?page=${page}&per_page=10`;
      if (status) {
        url += `&status=${status}`;
      }
      const data = await api.get<PaginatedInvites>(url);
      setData(data);
    } catch (err) {
      setData(null);
      setError(err instanceof Error ? err.message : "Failed to load invites");
    }
  }, []);

  useEffect(() => {
    if (user && isAuthorized) {
      fetchUsers();
      fetchInvites(page, statusFilter);
    }
  }, [user, page, statusFilter, isAuthorized, fetchUsers, fetchInvites]);

  const handleCreateInvite = async () => {
    if (!newGodfatherId) {
      setCreateError("Please select a godfather");
      return;
    }

    setIsCreating(true);
    setCreateError(null);

    try {
      await api.post("/api/admin/invites", {
        godfather_id: parseInt(newGodfatherId),
      });
      setNewGodfatherId("");
      fetchInvites(1, statusFilter);
      setPage(1);
    } catch (err) {
      setCreateError(err instanceof Error ? err.message : "Failed to create invite");
    } finally {
      setIsCreating(false);
    }
  };

  const handleRevoke = async (inviteId: number) => {
    try {
      await api.post(`/api/admin/invites/${inviteId}/revoke`);
      setError(null);
      fetchInvites(page, statusFilter);
    } catch (err) {
      setError(err instanceof Error ? err.message : "Failed to revoke invite");
    }
  };

  const formatDate = (dateStr: string) => {
    return new Date(dateStr).toLocaleString();
  };

  const getStatusBadgeStyle = (status: string) => {
    switch (status) {
      case READY:
        return badgeStyles.badgeReady;
      case SPENT:
        return badgeStyles.badgeSuccess;
      case REVOKED:
        return badgeStyles.badgeError;
      default:
        return {};
    }
  };

  if (isLoading) {
    return (
      <main style={layoutStyles.main}>
        <div style={layoutStyles.loader}>Loading...</div>
      </main>
    );
  }

  if (!user || !isAuthorized) {
    return null;
  }

  return (
    <main style={layoutStyles.main}>
      <Header currentPage="admin-invites" />

      <div style={layoutStyles.contentScrollable}>
        <div style={styles.pageContainer}>
          {/* Create Invite Section */}
          <div style={styles.createCard}>
            <h2 style={styles.createTitle}>Create Invite</h2>
            <div style={styles.createForm}>
              <div style={formStyles.field}>
                <label style={styles.inputLabel}>Godfather (user who can share this invite)</label>
                <select
                  value={newGodfatherId}
                  onChange={(e) => setNewGodfatherId(e.target.value)}
                  style={{ ...formStyles.select, maxWidth: "400px" }}
                >
                  <option value="">Select a user...</option>
                  {users.map((u) => (
                    <option key={u.id} value={u.id}>
                      {u.email}
                    </option>
                  ))}
                </select>
                {users.length === 0 && (
                  <span style={formStyles.hint}>
                    No users loaded yet. Create at least one invite to populate the list.
                  </span>
                )}
              </div>
              {createError && <div style={styles.createError}>{createError}</div>}
              <button
                onClick={handleCreateInvite}
                disabled={isCreating || !newGodfatherId}
                style={{
                  ...buttonStyles.accentButton,
                  alignSelf: "flex-start",
                  ...(!newGodfatherId ? buttonStyles.buttonDisabled : {}),
                }}
              >
                {isCreating ? "Creating..." : "Create Invite"}
              </button>
            </div>
          </div>

          {/* Invites Table */}
          <div style={cardStyles.tableCard}>
            <div style={tableStyles.tableHeader}>
              <h2 style={tableStyles.tableTitle}>All Invites</h2>
              <div style={utilityStyles.filterGroup}>
                <select
                  value={statusFilter}
                  onChange={(e) => {
                    setStatusFilter(e.target.value);
                    setPage(1);
                  }}
                  style={styles.filterSelect}
                >
                  <option value="">All statuses</option>
                  <option value={READY}>Ready</option>
                  <option value={SPENT}>Spent</option>
                  <option value={REVOKED}>Revoked</option>
                </select>
                <span style={tableStyles.totalCount}>{data?.total ?? 0} invites</span>
              </div>
            </div>

            <div style={tableStyles.tableWrapper}>
              <table style={tableStyles.table}>
                <thead>
                  <tr>
                    <th style={tableStyles.th}>Code</th>
                    <th style={tableStyles.th}>Godfather</th>
                    <th style={tableStyles.th}>Status</th>
                    <th style={tableStyles.th}>Used By</th>
                    <th style={tableStyles.th}>Created</th>
                    <th style={tableStyles.th}>Actions</th>
                  </tr>
                </thead>
                <tbody>
                  {error && (
                    <tr>
                      <td colSpan={6} style={tableStyles.errorRow}>
                        {error}
                      </td>
                    </tr>
                  )}
                  {!error &&
                    data?.records.map((record) => (
                      <tr key={record.id} style={tableStyles.tr}>
                        <td style={tableStyles.tdMono}>{record.identifier}</td>
                        <td style={tableStyles.td}>{record.godfather_email}</td>
                        <td style={tableStyles.td}>
                          <span
                            style={{ ...badgeStyles.badge, ...getStatusBadgeStyle(record.status) }}
                          >
                            {record.status}
                          </span>
                        </td>
                        <td style={tableStyles.td}>{record.used_by_email || "-"}</td>
                        <td style={tableStyles.tdDate}>{formatDate(record.created_at)}</td>
                        <td style={tableStyles.td}>
                          {record.status === READY && (
                            <button
                              onClick={() => handleRevoke(record.id)}
                              style={buttonStyles.dangerButton}
                            >
                              Revoke
                            </button>
                          )}
                        </td>
                      </tr>
                    ))}
                  {!error && (!data || data.records.length === 0) && (
                    <tr>
                      <td colSpan={6} style={tableStyles.emptyRow}>
                        No invites yet
                      </td>
                    </tr>
                  )}
                </tbody>
              </table>
            </div>

            {data && data.total_pages > 1 && (
              <div style={paginationStyles.pagination}>
                <button
                  onClick={() => setPage((p) => Math.max(1, p - 1))}
                  disabled={page === 1}
                  style={paginationStyles.pageBtn}
                >
                  ←
                </button>
                <span style={paginationStyles.pageInfo}>
                  {page} / {data.total_pages}
                </span>
                <button
                  onClick={() => setPage((p) => Math.min(data.total_pages, p + 1))}
                  disabled={page === data.total_pages}
                  style={paginationStyles.pageBtn}
                >
                  →
                </button>
              </div>
            )}
          </div>
        </div>
      </div>
    </main>
  );
}

// Page-specific styles
const styles: Record<string, React.CSSProperties> = {
  pageContainer: {
    display: "flex",
    flexDirection: "column",
    gap: "2rem",
    maxWidth: "1000px",
    margin: "0 auto",
  },
  createCard: {
    background: "rgba(99, 102, 241, 0.08)",
    border: "1px solid rgba(99, 102, 241, 0.2)",
    borderRadius: "16px",
    padding: "1.5rem",
  },
  createTitle: {
    fontFamily: "'DM Sans', system-ui, sans-serif",
    fontSize: "1rem",
    fontWeight: 600,
    color: "rgba(255, 255, 255, 0.9)",
    margin: "0 0 1rem 0",
  },
  createForm: {
    display: "flex",
    flexDirection: "column",
    gap: "1rem",
  },
  inputLabel: {
    fontFamily: "'DM Sans', system-ui, sans-serif",
    fontSize: "0.8rem",
    color: "rgba(255, 255, 255, 0.5)",
  },
  createError: {
    fontFamily: "'DM Sans', system-ui, sans-serif",
    fontSize: "0.85rem",
    color: "#f87171",
  },
  filterSelect: {
    fontFamily: "'DM Sans', system-ui, sans-serif",
    fontSize: "0.85rem",
    padding: "0.5rem 1rem",
    background: "rgba(255, 255, 255, 0.05)",
    border: "1px solid rgba(255, 255, 255, 0.1)",
    borderRadius: "8px",
    color: "#fff",
    cursor: "pointer",
  },
};
