'use client';

import { useEffect, useState } from 'react';

import { useApiClient } from '@/lib/apiClient';

interface StudioAccessStatus {
  user_id: string;
  user_handle: string;
  can_use_studio: boolean;
  is_on_waitlist: boolean;
  waitlist_rank: number | null;
  owned_invite_code: string | null;
  owned_invite_code_count: number | null;
  owned_invite_code_redeemed_count: number | null;
  invited_by: string | null;
}

interface StudioAccessSummary {
  num_users_on_waitlist: number;
  num_users_redeemed_code: number;
  num_unique_invite_codes: number;
}

interface StudioAccessInvitations {
  invitations: [string, string][]; // [inviter_handle, invitee_handle]
  updated_at: string;
}

interface BatchOperationResult {
  success_users: string[];
  failed_users: string[];
}

interface BulkAdmitUsersResult {
  admitted_users: string[];
  already_had_access_users: string[];
  failed_to_admit_users: string[];
}

type QueryType = 'handle' | 'email' | 'phone';
type BatchOperationType = 'generate' | 'delete' | 'access';

export default function StudioAccessClient() {
  // Summary state
  const [summary, setSummary] = useState<StudioAccessSummary | null>(null);
  const [summaryLoading, setSummaryLoading] = useState(true);
  const [summaryError, setSummaryError] = useState<string | null>(null);

  // Single user check state
  const [queryType, setQueryType] = useState<QueryType>('handle');
  const [queryValue, setQueryValue] = useState('');
  const [userResults, setUserResults] = useState<StudioAccessStatus | null>(
    null
  );
  const [userLoading, setUserLoading] = useState(false);
  const [userError, setUserError] = useState<string | null>(null);

  // Invitations state
  const [invitations, setInvitations] = useState<[string, string][]>([]);
  const [invitationsLoading, setInvitationsLoading] = useState(false);
  const [invitationsError, setInvitationsError] = useState<string | null>(null);
  const [hasMoreInvitations, setHasMoreInvitations] = useState(true);
  const [lastCursor, setLastCursor] = useState<string | null>(null);

  // Batch operations state
  const [batchOperationType, setBatchOperationType] =
    useState<BatchOperationType>('generate');
  const [batchQueryType, setBatchQueryType] = useState<QueryType>('handle');
  const [batchInputValue, setBatchInputValue] = useState('');
  const [batchCount, setBatchCount] = useState(1);
  const [batchResults, setBatchResults] = useState<
    BatchOperationResult | BulkAdmitUsersResult | null
  >(null);
  const [batchLoading, setBatchLoading] = useState(false);
  const [batchError, setBatchError] = useState<string | null>(null);

  // CSV upload state
  const [csvFile, setCsvFile] = useState<File | null>(null);
  const [csvPreview, setCsvPreview] = useState<string[]>([]);
  const [csvColumn, setCsvColumn] = useState<string>('');
  const [csvHeaders, setCsvHeaders] = useState<string[]>([]);

  const apiClient = useApiClient();

  // Load summary on component mount
  useEffect(() => {
    loadSummary();
  }, []);

  const loadSummary = async () => {
    setSummaryLoading(true);
    setSummaryError(null);

    try {
      const { data, error } = await apiClient.GET('/api/studio/access-summary');

      if (error) {
        throw new Error('Failed to fetch summary');
      }

      setSummary(data as StudioAccessSummary);
    } catch (err) {
      setSummaryError(
        err instanceof Error ? err.message : 'Something went wrong'
      );
    } finally {
      setSummaryLoading(false);
    }
  };

  const handleUserSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    if (!queryValue.trim()) {
      setUserError('Please enter a value to query');
      setUserResults(null); // Clear previous results
      return;
    }

    setUserLoading(true);
    setUserError(null);
    setUserResults(null); // Clear previous results when starting new search

    try {
      // Build query parameters based on the selected type
      const queryParams: any = {};
      if (queryType === 'handle') {
        queryParams.handle = queryValue;
      } else if (queryType === 'email') {
        queryParams.email = queryValue;
      } else if (queryType === 'phone') {
        queryParams.phone_number = queryValue;
      }

      const { data, error } = await apiClient.GET('/api/studio/access-status', {
        params: {
          query: queryParams,
        },
      });

      if (error) {
        throw new Error('Failed to fetch access status');
      }

      setUserResults(data);
    } catch (err) {
      setUserError(err instanceof Error ? err.message : 'Something went wrong');
    } finally {
      setUserLoading(false);
    }
  };

  const loadInvitations = async (cursor?: string) => {
    setInvitationsLoading(true);
    setInvitationsError(null);

    try {
      const params: any = { limit: 20 };
      if (cursor) {
        params.cursor = cursor;
      }

      const { data, error } = await apiClient.GET(
        '/api/studio/access-invitations',
        {
          params: {
            query: params,
          },
        }
      );

      if (error) {
        throw new Error('Failed to fetch invitations');
      }

      const invitationsData = data as StudioAccessInvitations;

      if (cursor) {
        // Append to existing invitations
        setInvitations((prev) => [...prev, ...invitationsData.invitations]);
      } else {
        // Replace invitations
        setInvitations(invitationsData.invitations);
      }

      // Check if we have more invitations
      setHasMoreInvitations(invitationsData.invitations.length === 20);
      setLastCursor(invitationsData.updated_at);
    } catch (err) {
      setInvitationsError(
        err instanceof Error ? err.message : 'Something went wrong'
      );
    } finally {
      setInvitationsLoading(false);
    }
  };

  const loadMoreInvitations = () => {
    if (!invitationsLoading && hasMoreInvitations && lastCursor) {
      loadInvitations(lastCursor);
    }
  };

  const isBulkAdmitUsersResult = (
    result: BatchOperationResult | BulkAdmitUsersResult
  ): result is BulkAdmitUsersResult => {
    return (
      'admitted_users' in result &&
      'already_had_access_users' in result &&
      'failed_to_admit_users' in result
    );
  };

  const isBatchOperationResult = (
    result: BatchOperationResult | BulkAdmitUsersResult
  ): result is BatchOperationResult => {
    return 'success_users' in result && 'failed_users' in result;
  };

  const handleBatchOperation = async (e: React.FormEvent) => {
    e.preventDefault();
    if (!batchInputValue.trim()) {
      setBatchError('Please enter values to process');
      return;
    }

    setBatchLoading(true);
    setBatchError(null);
    setBatchResults(null);

    try {
      const values = batchInputValue
        .split('\n')
        .map((v) => v.trim())
        .filter((v) => v.length > 0);

      if (values.length === 0) {
        throw new Error('No valid values provided');
      }

      const payload: any = {
        count: batchCount,
      };

      if (batchQueryType === 'handle') {
        payload.handles = values;
      } else if (batchQueryType === 'email') {
        payload.emails = values;
      } else if (batchQueryType === 'phone') {
        payload.phone_numbers = values;
      }

      if (batchOperationType === 'generate') {
        const { data, error } = await apiClient.POST(
          '/api/studio/sudo-generate-codes',
          {
            body: payload,
          }
        );
        if (error) {
          throw new Error('Failed to generate codes');
        }
        setBatchResults(data as BatchOperationResult);
      } else if (batchOperationType === 'delete') {
        const { data, error } = await apiClient.DELETE(
          '/api/studio/sudo-delete-codes',
          {
            body: payload,
          }
        );
        if (error) {
          throw new Error('Failed to delete codes');
        }
        setBatchResults(data as BatchOperationResult);
      } else if (batchOperationType === 'access') {
        const { data, error } = await apiClient.POST(
          '/api/studio/bulk-admit-users',
          {
            body: payload,
          }
        );
        if (error) {
          throw new Error('Failed to grant access');
        }
        setBatchResults(data as BulkAdmitUsersResult);
      }
    } catch (err) {
      setBatchError(
        err instanceof Error ? err.message : 'Something went wrong'
      );
    } finally {
      setBatchLoading(false);
    }
  };

  const handleCsvUpload = (file: File) => {
    setCsvFile(file);
    setCsvPreview([]);
    setCsvHeaders([]);
    setCsvColumn('');

    const reader = new FileReader();
    reader.onload = (e) => {
      const text = e.target?.result as string;
      const lines = text.split('\n');
      const headers =
        lines[0]?.split(',').map((h) => h.trim().replace(/"/g, '')) || [];
      const preview = lines
        .slice(1, 6)
        .map((line) => line.trim())
        .filter((line) => line.length > 0);

      setCsvHeaders(headers);
      setCsvPreview(preview);
      if (headers.length > 0) {
        setCsvColumn(headers[0]);
      }
    };
    reader.readAsText(file);
  };

  const handleCsvBatchOperation = async () => {
    if (!csvFile || !csvColumn) {
      setBatchError('Please select a CSV file and column');
      return;
    }

    setBatchLoading(true);
    setBatchError(null);
    setBatchResults(null);

    try {
      const text = await csvFile.text();
      const lines = text.split('\n');
      const headers =
        lines[0]?.split(',').map((h) => h.trim().replace(/"/g, '')) || [];
      const columnIndex = headers.indexOf(csvColumn);

      if (columnIndex === -1) {
        throw new Error(`Column "${csvColumn}" not found in CSV`);
      }

      const values = lines
        .slice(1)
        .map((line) => line.split(',')[columnIndex]?.trim().replace(/"/g, ''))
        .filter((v) => v && v.length > 0);

      if (values.length === 0) {
        throw new Error('No valid values found in selected column');
      }

      const payload: any = {
        count: batchCount,
      };

      if (batchQueryType === 'handle') {
        payload.handles = values;
      } else if (batchQueryType === 'email') {
        payload.emails = values;
      } else if (batchQueryType === 'phone') {
        payload.phone_numbers = values;
      }

      if (batchOperationType === 'generate') {
        const { data, error } = await apiClient.POST(
          '/api/studio/sudo-generate-codes',
          {
            body: payload,
          }
        );
        if (error) {
          throw new Error('Failed to generate codes');
        }
        setBatchResults(data as BatchOperationResult);
      } else if (batchOperationType === 'delete') {
        const { data, error } = await apiClient.DELETE(
          '/api/studio/sudo-delete-codes',
          {
            body: payload,
          }
        );
        if (error) {
          throw new Error('Failed to delete codes');
        }
        setBatchResults(data as BatchOperationResult);
      } else if (batchOperationType === 'access') {
        const { data, error } = await apiClient.POST(
          '/api/studio/bulk-admit-users',
          {
            body: payload,
          }
        );
        if (error) {
          throw new Error('Failed to grant access');
        }
        setBatchResults(data as BulkAdmitUsersResult);
      }
    } catch (err) {
      setBatchError(
        err instanceof Error ? err.message : 'Something went wrong'
      );
    } finally {
      setBatchLoading(false);
    }
  };

  // Load initial invitations
  useEffect(() => {
    loadInvitations();
  }, []);

  return (
    <div className='w-full overflow-y-auto bg-gray-100 pb-40'>
      <div className='w-full space-y-8 p-6'>
        {/* Summary Section */}
        <div className='rounded-lg border border-gray-300 bg-gray-50 p-6 shadow-sm'>
          <h2 className='mb-4 text-xl font-semibold text-gray-900'>
            Studio Access Summary
          </h2>
          {summaryLoading ? (
            <div className='text-center text-gray-600'>Loading summary...</div>
          ) : summaryError ? (
            <div className='text-center text-red-600'>{summaryError}</div>
          ) : summary ? (
            <div className='grid grid-cols-1 gap-4 md:grid-cols-3'>
              <div className='text-center'>
                <p className='text-2xl font-bold text-blue-600'>
                  {summary.num_users_on_waitlist}
                </p>
                <p className='text-sm text-gray-600'>Users on Waitlist</p>
              </div>
              <div className='text-center'>
                <p className='text-2xl font-bold text-green-600'>
                  {summary.num_users_redeemed_code}
                </p>
                <p className='text-sm text-gray-600'>
                  Users Who Redeemed Codes
                </p>
              </div>
              <div className='text-center'>
                <p className='text-2xl font-bold text-purple-600'>
                  {summary.num_unique_invite_codes}
                </p>
                <p className='text-sm text-gray-600'>Unique Invite Codes</p>
              </div>
            </div>
          ) : null}
        </div>

        {/* Single User Check Section */}
        <div className='rounded-lg border border-gray-300 bg-gray-50 p-6 shadow-sm'>
          <h2 className='mb-4 text-xl font-semibold text-gray-900'>
            Check User Access Status
          </h2>
          <form
            onSubmit={handleUserSubmit}
            className='mb-6 flex flex-col gap-4'
          >
            <div className='flex flex-col gap-4 md:flex-row'>
              <div className='flex flex-col gap-2 md:w-1/4'>
                <label className='text-sm font-medium'>Query Type</label>
                <select
                  value={queryType}
                  onChange={(e) => setQueryType(e.target.value as QueryType)}
                  className='rounded-md border border-gray-300 p-2'
                >
                  <option value='handle'>Handle</option>
                  <option value='email'>Email</option>
                  <option value='phone'>Phone Number</option>
                </select>
              </div>
              <div className='flex flex-col gap-2 md:w-3/4'>
                <label className='text-sm font-medium'>
                  {queryType === 'handle'
                    ? 'Handle'
                    : queryType === 'email'
                      ? 'Email'
                      : 'Phone Number'}
                </label>
                <input
                  type={queryType === 'email' ? 'email' : 'text'}
                  value={queryValue}
                  onChange={(e) => setQueryValue(e.target.value)}
                  placeholder={`Enter ${queryType}...`}
                  className='rounded-md border border-gray-300 p-2'
                  required
                />
              </div>
            </div>
            <div className='flex justify-center'>
              <button
                type='submit'
                disabled={userLoading}
                className='rounded-md bg-blue-500 px-6 py-2 text-white hover:bg-blue-600 disabled:bg-blue-300'
              >
                {userLoading ? 'Loading...' : 'Check Access Status'}
              </button>
            </div>
          </form>

          {userError && (
            <div className='mb-4 rounded-md bg-red-50 p-4 text-center text-red-500'>
              {userError}
            </div>
          )}

          {userResults && (
            <div className='rounded-lg border border-gray-300 bg-gray-50 p-6 shadow-sm'>
              <h3 className='mb-4 text-lg font-semibold text-gray-900'>
                Access Status Results
              </h3>
              <div className='grid grid-cols-1 gap-4 md:grid-cols-2'>
                <div>
                  <p className='text-sm text-gray-600'>User ID</p>
                  <p className='font-medium text-gray-900'>
                    {userResults.user_id}
                  </p>
                </div>
                <div>
                  <p className='text-sm text-gray-600'>Handle</p>
                  <p className='font-medium text-gray-900'>
                    {userResults.user_handle}
                  </p>
                </div>
                <div>
                  <p className='text-sm text-gray-600'>Can Use Studio</p>
                  <p
                    className={`font-medium ${userResults.can_use_studio ? 'text-green-600' : 'text-red-600'}`}
                  >
                    {userResults.can_use_studio ? 'Yes' : 'No'}
                  </p>
                </div>
                <div>
                  <p className='text-sm text-gray-600'>On Waitlist</p>
                  <p
                    className={`font-medium ${userResults.is_on_waitlist ? 'text-orange-600' : 'text-gray-700'}`}
                  >
                    {userResults.is_on_waitlist ? 'Yes' : 'No'}
                  </p>
                </div>
                {userResults.waitlist_rank !== null && (
                  <div>
                    <p className='text-sm text-gray-600'>Waitlist Rank</p>
                    <p className='font-medium text-gray-900'>
                      {userResults.waitlist_rank}
                    </p>
                  </div>
                )}
                {userResults.owned_invite_code && (
                  <div>
                    <p className='text-sm text-gray-600'>Owned Invite Code</p>
                    <p className='font-mono text-sm font-medium text-gray-900'>
                      {userResults.owned_invite_code}
                    </p>
                  </div>
                )}
                {userResults.owned_invite_code_count !== null && (
                  <div>
                    <p className='text-sm text-gray-600'>Total Codes</p>
                    <p className='font-medium text-gray-900'>
                      {userResults.owned_invite_code_count}
                    </p>
                  </div>
                )}
                {userResults.owned_invite_code_redeemed_count !== null && (
                  <div>
                    <p className='text-sm text-gray-600'>Redeemed Codes</p>
                    <p className='font-medium text-gray-900'>
                      {userResults.owned_invite_code_redeemed_count}
                    </p>
                  </div>
                )}
                {userResults.invited_by && (
                  <div>
                    <p className='text-sm text-gray-600'>Invited By</p>
                    <p className='font-medium text-gray-900'>
                      {userResults.invited_by}
                    </p>
                  </div>
                )}
              </div>
            </div>
          )}
        </div>

        {/* Batch Operations Section */}
        <div className='rounded-lg border border-gray-300 bg-gray-50 p-6 shadow-sm'>
          <h2 className='mb-4 text-xl font-semibold text-gray-900'>
            Batch Operations
          </h2>

          {/* Operation Type Selection */}
          <div className='mb-6 flex gap-4'>
            <label className='flex items-center'>
              <input
                type='radio'
                value='generate'
                checked={batchOperationType === 'generate'}
                onChange={(e) =>
                  setBatchOperationType(e.target.value as BatchOperationType)
                }
                className='mr-2'
              />
              Generate Codes
            </label>
            <label className='flex items-center'>
              <input
                type='radio'
                value='delete'
                checked={batchOperationType === 'delete'}
                onChange={(e) =>
                  setBatchOperationType(e.target.value as BatchOperationType)
                }
                className='mr-2'
              />
              Delete Codes
            </label>
            <label className='flex items-center'>
              <input
                type='radio'
                value='access'
                checked={batchOperationType === 'access'}
                onChange={(e) => {
                  const newOperationType = e.target.value as BatchOperationType;
                  setBatchOperationType(newOperationType);
                  // Reset query type to 'handle' when switching to 'access' operation
                  if (
                    newOperationType === 'access' &&
                    batchQueryType !== 'handle'
                  ) {
                    setBatchQueryType('handle');
                  }
                }}
                className='mr-2'
              />
              Grant Access
            </label>
          </div>

          {/* Manual Input Section */}
          <div className='mb-6'>
            <h3 className='mb-3 text-lg font-medium text-gray-900'>
              Manual Input
            </h3>
            <form onSubmit={handleBatchOperation} className='space-y-4'>
              <div className='flex flex-col gap-4 md:flex-row'>
                <div className='flex flex-col gap-2 md:w-1/4'>
                  <label className='text-sm font-medium'>Query Type</label>
                  <select
                    value={batchQueryType}
                    onChange={(e) =>
                      setBatchQueryType(e.target.value as QueryType)
                    }
                    className='rounded-md border border-gray-300 p-2'
                  >
                    <option value='handle'>Handle</option>
                    {batchOperationType !== 'access' && (
                      <option value='email'>Email</option>
                    )}
                    {batchOperationType !== 'access' && (
                      <option value='phone'>Phone Number</option>
                    )}
                  </select>
                </div>
                <div className='flex flex-col gap-2 md:w-1/4'>
                  <label className='text-sm font-medium'>Count</label>
                  <input
                    type='number'
                    min='1'
                    value={batchCount}
                    onChange={(e) =>
                      setBatchCount(parseInt(e.target.value) || 1)
                    }
                    className='rounded-md border border-gray-300 p-2'
                  />
                </div>
              </div>
              <div>
                <label className='text-sm font-medium'>
                  {batchQueryType === 'handle'
                    ? 'Handles (one per line)'
                    : batchQueryType === 'email'
                      ? 'Emails (one per line)'
                      : 'Phone Numbers (one per line)'}
                </label>
                <textarea
                  value={batchInputValue}
                  onChange={(e) => setBatchInputValue(e.target.value)}
                  placeholder={`Enter ${batchQueryType}s, one per line...`}
                  rows={5}
                  className='mt-1 w-full rounded-md border border-gray-300 p-2'
                />
              </div>
              <button
                type='submit'
                disabled={batchLoading}
                className='rounded-md bg-blue-500 px-6 py-2 text-white hover:bg-blue-600 disabled:bg-blue-300'
              >
                {batchLoading
                  ? 'Processing...'
                  : batchOperationType === 'access'
                    ? 'Grant Access'
                    : `${batchOperationType === 'generate' ? 'Generate' : 'Delete'} Codes`}
              </button>
            </form>
          </div>

          {/* CSV Upload Section */}
          <div className='mb-6'>
            <h3 className='mb-3 text-lg font-medium text-gray-900'>
              CSV Upload
            </h3>
            <div className='space-y-4'>
              <div>
                <label className='text-sm font-medium'>Upload CSV File</label>
                <input
                  type='file'
                  accept='.csv'
                  onChange={(e) =>
                    e.target.files?.[0] && handleCsvUpload(e.target.files[0])
                  }
                  className='mt-1 block w-full text-sm text-gray-500 file:mr-4 file:rounded-md file:border-0 file:bg-blue-50 file:px-4 file:py-2 file:text-sm file:font-medium file:text-blue-700 hover:file:bg-blue-100'
                />
              </div>

              {csvHeaders.length > 0 && (
                <div>
                  <label className='text-sm font-medium'>Select Column</label>
                  <select
                    value={csvColumn}
                    onChange={(e) => setCsvColumn(e.target.value)}
                    className='mt-1 rounded-md border border-gray-300 p-2'
                  >
                    {csvHeaders.map((header) => (
                      <option key={header} value={header}>
                        {header}
                      </option>
                    ))}
                  </select>
                </div>
              )}

              {csvPreview.length > 0 && (
                <div>
                  <label className='text-sm font-medium'>
                    Preview (first 5 rows)
                  </label>
                  <div className='mt-1 max-h-32 overflow-y-auto rounded-md border border-gray-300 bg-white p-2'>
                    {csvPreview.map((row, index) => (
                      <div key={index} className='text-sm text-gray-700'>
                        {row}
                      </div>
                    ))}
                  </div>
                </div>
              )}

              {csvFile && csvColumn && (
                <button
                  onClick={handleCsvBatchOperation}
                  disabled={batchLoading}
                  className='rounded-md bg-green-500 px-6 py-2 text-white hover:bg-green-600 disabled:bg-green-300'
                >
                  {batchLoading
                    ? 'Processing...'
                    : `Process CSV (${
                        batchOperationType === 'access'
                          ? 'Grant Access'
                          : `${batchOperationType === 'generate' ? 'Generate' : 'Delete'} Codes`
                      })`}
                </button>
              )}
            </div>
          </div>

          {/* Results Section */}
          {batchError && (
            <div className='mb-4 rounded-md bg-red-50 p-4 text-center text-red-500'>
              {batchError}
            </div>
          )}

          {batchResults && (
            <div className='rounded-lg border border-gray-300 bg-gray-50 p-4'>
              <h3 className='mb-3 text-lg font-medium text-gray-900'>
                Results
              </h3>
              {isBatchOperationResult(batchResults) && (
                <div className='grid grid-cols-1 gap-4 md:grid-cols-2'>
                  <div>
                    <h4 className='mb-2 font-medium text-green-600'>
                      Successful ({batchResults.success_users.length})
                    </h4>
                    <div className='max-h-32 overflow-y-auto rounded-md border border-gray-200 bg-green-50 p-2'>
                      {batchResults.success_users.length > 0 ? (
                        batchResults.success_users.map((user, index) => (
                          <div key={index} className='text-sm text-green-700'>
                            {user}
                          </div>
                        ))
                      ) : (
                        <div className='text-sm text-gray-500'>None</div>
                      )}
                    </div>
                  </div>
                  <div>
                    <h4 className='mb-2 font-medium text-red-600'>
                      Failed ({batchResults.failed_users.length})
                    </h4>
                    <div className='max-h-32 overflow-y-auto rounded-md border border-gray-200 bg-red-50 p-2'>
                      {batchResults.failed_users.length > 0 ? (
                        batchResults.failed_users.map((user, index) => (
                          <div key={index} className='text-sm text-red-700'>
                            {user}
                          </div>
                        ))
                      ) : (
                        <div className='text-sm text-gray-500'>None</div>
                      )}
                    </div>
                  </div>
                </div>
              )}
              {isBulkAdmitUsersResult(batchResults) && (
                <div className='grid grid-cols-1 gap-4 md:grid-cols-3'>
                  <div>
                    <h4 className='mb-2 font-medium text-green-600'>
                      Successful ({batchResults.admitted_users.length})
                    </h4>
                    <div className='max-h-32 overflow-y-auto rounded-md border border-gray-200 bg-green-50 p-2'>
                      {batchResults.admitted_users.length > 0 ? (
                        batchResults.admitted_users.map((user, index) => (
                          <div key={index} className='text-sm text-green-700'>
                            {user}
                          </div>
                        ))
                      ) : (
                        <div className='text-sm text-gray-500'>None</div>
                      )}
                    </div>
                  </div>
                  <div>
                    <h4 className='mb-2 font-medium text-blue-600'>
                      Already had access (
                      {batchResults.already_had_access_users.length})
                    </h4>
                    <div className='max-h-32 overflow-y-auto rounded-md border border-gray-200 bg-blue-50 p-2'>
                      {batchResults.already_had_access_users.length > 0 ? (
                        batchResults.already_had_access_users.map(
                          (user, index) => (
                            <div key={index} className='text-sm text-blue-700'>
                              {user}
                            </div>
                          )
                        )
                      ) : (
                        <div className='text-sm text-gray-500'>None</div>
                      )}
                    </div>
                  </div>
                  <div>
                    <h4 className='mb-2 font-medium text-red-600'>
                      Failed ({batchResults.failed_to_admit_users.length})
                    </h4>
                    <div className='max-h-32 overflow-y-auto rounded-md border border-gray-200 bg-red-50 p-2'>
                      {batchResults.failed_to_admit_users.length > 0 ? (
                        batchResults.failed_to_admit_users.map(
                          (user, index) => (
                            <div key={index} className='text-sm text-red-700'>
                              {user}
                            </div>
                          )
                        )
                      ) : (
                        <div className='text-sm text-gray-500'>None</div>
                      )}
                    </div>
                  </div>
                </div>
              )}
            </div>
          )}
        </div>

        {/* Invitations Section */}
        <div className='rounded-lg border border-gray-300 bg-gray-50 p-6 shadow-sm'>
          <h2 className='mb-4 text-xl font-semibold text-gray-900'>
            Invitation Pairs
          </h2>
          <p className='mb-4 text-sm text-gray-600'>
            Showing inviter → invitee relationships
          </p>

          {invitationsError && (
            <div className='mb-4 rounded-md bg-red-50 p-4 text-center text-red-500'>
              {invitationsError}
            </div>
          )}

          <div className='max-h-96 overflow-y-auto'>
            {invitations.length === 0 && !invitationsLoading ? (
              <div className='py-8 text-center text-gray-600'>
                No invitations found
              </div>
            ) : (
              <div className='space-y-2'>
                {invitations.map(([inviter, invitee], index) => (
                  <div
                    key={index}
                    className='flex items-center justify-between rounded-md border border-gray-200 p-3 hover:bg-gray-50'
                  >
                    <div className='flex items-center space-x-2'>
                      <span className='font-medium text-gray-900'>
                        {inviter}
                      </span>
                      <span className='text-gray-400'>→</span>
                      <span className='font-medium text-gray-900'>
                        {invitee}
                      </span>
                    </div>
                  </div>
                ))}
              </div>
            )}

            {invitationsLoading && (
              <div className='py-4 text-center text-gray-600'>Loading...</div>
            )}

            {hasMoreInvitations && !invitationsLoading && (
              <div className='pt-4 text-center'>
                <button
                  onClick={loadMoreInvitations}
                  className='rounded-md bg-gray-500 px-4 py-2 text-white hover:bg-gray-600'
                >
                  Load More
                </button>
              </div>
            )}
          </div>
        </div>
      </div>
    </div>
  );
}
