'use client';

/**
 * Dealer Table Component
 *
 * Paginated table of dealers with quick actions menu.
 */

import React, { useState } from 'react';
import styles from './DealerTable.module.css';
import { QuickActionsMenu } from './QuickActionsMenu';
import { EditDNSModal } from './EditDNSModal';
import { StatusChangeModal } from './StatusChangeModal';
import { DealerDetailModal } from './DealerDetailModal';
import { STATUS_LABELS } from '@/lib/status-transitions';
import { useToast } from '@/components/ui/Toast';
import { getDealerSiteHost, getDealerSiteUrl } from '@/lib/dealer-site-url';

interface Dealer {
  id: string;
  userId: string;
  subdomain: string | null;
  domain: string;
  domainPrefix?: string;
  subscriptionTier: string;
  status: string;
  dealerNumber: string | null;
  businessName: string | null;
  contactName: string | null;
  stripeCustomerId: string | null;
  createdAt: string;
  lastPublishedAt: string | null;
  hasPendingReindex?: boolean;
  user: {
    id: string;
    email: string;
    name: string | null;
    image: string | null;
    role: string;
  };
}

interface Pagination {
  page: number;
  limit: number;
  total: number;
  totalPages: number;
}

interface DealerTableProps {
  dealers: Dealer[];
  pagination: Pagination;
  onPageChange: (page: number) => void;
  onImpersonate: (userId: string) => void;
  onDealerUpdated?: () => void | Promise<void>;
  isLoading?: boolean;
  isImpersonating?: string | null;
  sortBy?: string;
  sortOrder?: 'asc' | 'desc';
  onSort?: (field: string, order: 'asc' | 'desc') => void;
}

// Default sort direction for each column when first clicked
const DEFAULT_SORT_DIRECTIONS: Record<string, 'asc' | 'desc'> = {
  businessName: 'asc',
  subdomain: 'asc',
  tier: 'asc',
  status: 'asc',
  createdAt: 'desc',
};

// Column definitions for sortable headers
const SORTABLE_COLUMNS: Array<{ key: string; label: string }> = [
  { key: 'businessName', label: 'Dealer' },
  { key: 'subdomain', label: 'Subdomain' },
  { key: 'tier', label: 'Tier' },
  { key: 'status', label: 'Status' },
  { key: 'createdAt', label: 'Created' },
];

const TIER_COLORS: Record<string, string> = {
  starter: '#6b7280',
  growth: '#3b82f6',
  enhanced: '#8b5cf6',
  professional: '#f59e0b',
};

const STATUS_COLORS: Record<string, string> = {
  active: '#10b981',
  pending: '#f59e0b',
  suspended: '#ef4444',
  cancelled: '#6b7280',
  cancelled_pending: '#f59e0b',
  payment_failed: '#ef4444',
};

export function DealerTable({
  dealers,
  pagination,
  onPageChange,
  onImpersonate,
  onDealerUpdated,
  isLoading,
  isImpersonating,
  sortBy = 'createdAt',
  sortOrder = 'desc',
  onSort,
}: DealerTableProps) {
  const [editingDealer, setEditingDealer] = useState<Dealer | null>(null);
  const [isEditDNSOpen, setIsEditDNSOpen] = useState(false);
  const [isStatusChangeOpen, setIsStatusChangeOpen] = useState(false);
  const [statusChangeDealer, setStatusChangeDealer] = useState<Dealer | null>(null);
  const [selectedDealerId, setSelectedDealerId] = useState<string | null>(null);
  const [regeneratingDealerId, setRegeneratingDealerId] = useState<string | null>(null);
  const [reindexingDealerId, setReindexingDealerId] = useState<string | null>(null);
  const { showToast } = useToast();

  const handleColumnSort = (field: string) => {
    if (!onSort) return;
    if (sortBy === field) {
      // Toggle direction when clicking the same column
      onSort(field, sortOrder === 'asc' ? 'desc' : 'asc');
    } else {
      // Use default direction for the new column
      onSort(field, DEFAULT_SORT_DIRECTIONS[field] || 'asc');
    }
  };

  const formatDate = (dateStr: string) => {
    return new Date(dateStr).toLocaleDateString('en-US', {
      year: 'numeric',
      month: 'short',
      day: 'numeric',
    });
  };

  const handleEditDNS = (dealer: Dealer) => {
    setEditingDealer(dealer);
    setIsEditDNSOpen(true);
  };

  const handleChangeStatus = (dealer: Dealer, e?: React.MouseEvent) => {
    e?.stopPropagation();
    setStatusChangeDealer(dealer);
    setIsStatusChangeOpen(true);
  };

  const handleSaveStatus = async (
    dealerId: string,
    status: string,
    reason: string,
    notes?: string,
    cancellationMode?: string
  ) => {
    const response = await fetch(`/api/admin/dealers/${dealerId}/status`, {
      method: 'PATCH',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ status, reason, notes, cancellationMode }),
    });

    if (!response.ok) {
      const data = await response.json();
      throw new Error(data.error || 'Failed to update status');
    }

    // Refresh the dealer list
    await onDealerUpdated?.();
  };

  const handleSaveSubdomain = async (
    dealerId: string,
    newSubdomain: string,
    domainPrefix: string,
    domain: string,
    bypassProhibitedTerms?: boolean
  ) => {
    const response = await fetch(`/api/admin/dealers/${dealerId}/subdomain`, {
      method: 'PATCH',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        subdomain: newSubdomain,
        domainPrefix,
        domain,
        bypassProhibitedTerms,
      }),
    });

    if (!response.ok) {
      const data = await response.json();
      throw new Error(data.error || 'Failed to update subdomain');
    }

    const data = await response.json();

    // Refresh the dealer list and wait for it to complete
    await onDealerUpdated?.();

    return { siblings: data.siblings };
  };

  const handleRegeneratePages = async (dealerId: string) => {
    setRegeneratingDealerId(dealerId);
    try {
      const response = await fetch(`/api/admin/dealers/${dealerId}/revalidate`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
      });

      const data = await response.json();

      if (!response.ok) {
        throw new Error(data.error || 'Failed to regenerate pages');
      }

      // Show success/warning feedback via toast
      if (data.warning) {
        showToast(
          `Regenerated ${data.successCount}/${data.totalPages} pages. ${data.warning}`,
          'warning'
        );
      } else {
        showToast(
          `Successfully regenerated ${data.totalPages} page${data.totalPages === 1 ? '' : 's'}.`,
          'success'
        );
      }
    } catch (error) {
      console.error('[DealerTable] Page regeneration failed:', {
        dealerId,
        error: error instanceof Error ? error.message : error,
      });
      const message = error instanceof Error ? error.message : 'Failed to regenerate pages';
      showToast(`Failed to regenerate pages: ${message}`, 'error');
    } finally {
      setRegeneratingDealerId(null);
    }
  };

  const handleReindexGSC = async (dealerId: string) => {
    setReindexingDealerId(dealerId);
    try {
      const res = await fetch(`/api/admin/dealers/${dealerId}/reindex-gsc`, { method: 'POST' });
      if (!res.ok) {
        const data = await res.json().catch(() => ({}));
        throw new Error(data.error || `HTTP ${res.status}`);
      }
      showToast('Reindex with Google queued successfully.', 'success');
    } catch (error) {
      console.error('[DealerTable] GSC reindex failed:', {
        dealerId,
        error: error instanceof Error ? error.message : error,
      });
      const message = error instanceof Error ? error.message : 'Failed to queue reindex';
      showToast(`Failed to queue reindex: ${message}`, 'error');
    } finally {
      setReindexingDealerId(null);
    }
  };

  // Only show full spinner on initial load (no data yet)
  if (isLoading && dealers.length === 0) {
    return (
      <div className={styles.loadingContainer}>
        <div className={styles.spinner}></div>
        <span>Loading dealers...</span>
      </div>
    );
  }

  if (!isLoading && dealers.length === 0) {
    return (
      <div className={styles.emptyState}>
        <svg
          className={styles.emptyIcon}
          viewBox="0 0 24 24"
          fill="none"
          stroke="currentColor"
          strokeWidth="1.5"
        >
          <path
            strokeLinecap="round"
            strokeLinejoin="round"
            d="M15 19.128a9.38 9.38 0 002.625.372 9.337 9.337 0 004.121-.952 4.125 4.125 0 00-7.533-2.493M15 19.128v-.003c0-1.113-.285-2.16-.786-3.07M15 19.128v.106A12.318 12.318 0 018.624 21c-2.331 0-4.512-.645-6.374-1.766l-.001-.109a6.375 6.375 0 0111.964-3.07M12 6.375a3.375 3.375 0 11-6.75 0 3.375 3.375 0 016.75 0zm8.25 2.25a2.625 2.625 0 11-5.25 0 2.625 2.625 0 015.25 0z"
          />
        </svg>
        <p>No dealers found</p>
        <span className={styles.emptyHint}>Try adjusting your search or filters</span>
      </div>
    );
  }

  return (
    <>
      <div className={styles.container}>
        <div className={`${styles.tableWrapper} ${isLoading ? styles.tableLoading : ''}`}>
          <table className={styles.table}>
            <thead>
              <tr>
                {SORTABLE_COLUMNS.map((col) => (
                  <th key={col.key} className={sortBy === col.key ? styles.sortActive : ''}>
                    <button
                      className={styles.sortButton}
                      onClick={() => handleColumnSort(col.key)}
                      aria-sort={
                        sortBy === col.key
                          ? sortOrder === 'asc'
                            ? 'ascending'
                            : 'descending'
                          : 'none'
                      }
                    >
                      {col.label}
                      <span className={styles.sortArrow} aria-hidden="true">
                        {sortBy === col.key
                          ? sortOrder === 'asc'
                            ? '\u25B2'
                            : '\u25BC'
                          : '\u25BC'}
                      </span>
                    </button>
                  </th>
                ))}
                <th>Actions</th>
              </tr>
            </thead>
            <tbody>
              {dealers.map((dealer) => (
                <tr key={dealer.id}>
                  <td>
                    <button
                      className={styles.dealerInfoButton}
                      onClick={() => setSelectedDealerId(dealer.id)}
                      title="Click to view dealer details"
                    >
                      <div className={styles.dealerInfo}>
                        <div className={styles.dealerPrimary}>
                          {dealer.businessName ||
                            dealer.contactName ||
                            dealer.user.name ||
                            dealer.user.email}
                        </div>
                        <div className={styles.dealerSecondary}>{dealer.user.email}</div>
                        {dealer.dealerNumber && (
                          <div className={styles.dealerNumber}>#{dealer.dealerNumber}</div>
                        )}
                      </div>
                    </button>
                  </td>
                  <td>
                    <div className={styles.subdomainCell}>
                      <button
                        className={styles.subdomainButton}
                        onClick={(e) => {
                          e.stopPropagation();
                          handleEditDNS(dealer);
                        }}
                        title="Click to edit subdomain"
                      >
                        {dealer.subdomain ? (
                          <code className={styles.subdomain}>{getDealerSiteHost(dealer)}</code>
                        ) : (
                          <span className={styles.noSubdomain}>Not set</span>
                        )}
                      </button>
                      {dealer.subdomain && (
                        <a
                          href={getDealerSiteUrl(dealer) ?? '#'}
                          target="_blank"
                          rel="noopener noreferrer"
                          className={styles.iconButton}
                          title="Open site in new tab"
                          onClick={(e) => e.stopPropagation()}
                        >
                          <svg
                            width="14"
                            height="14"
                            viewBox="0 0 24 24"
                            fill="none"
                            stroke="currentColor"
                            strokeWidth="2"
                            strokeLinecap="round"
                            strokeLinejoin="round"
                          >
                            <path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" />
                            <polyline points="15 3 21 3 21 9" />
                            <line x1="10" y1="14" x2="21" y2="3" />
                          </svg>
                        </a>
                      )}
                    </div>
                  </td>
                  <td>
                    <span
                      className={styles.badge}
                      style={{ backgroundColor: TIER_COLORS[dealer.subscriptionTier] || '#6b7280' }}
                    >
                      {dealer.subscriptionTier}
                    </span>
                  </td>
                  <td>
                    <button
                      className={styles.statusButton}
                      onClick={(e) => handleChangeStatus(dealer, e)}
                      title="Click to change status"
                    >
                      <span
                        className={styles.statusBadge}
                        style={{ borderColor: STATUS_COLORS[dealer.status] || '#6b7280' }}
                      >
                        <span
                          className={styles.statusDot}
                          style={{ backgroundColor: STATUS_COLORS[dealer.status] || '#6b7280' }}
                        ></span>
                        {STATUS_LABELS[dealer.status as keyof typeof STATUS_LABELS] ||
                          dealer.status}
                      </span>
                    </button>
                  </td>
                  <td className={styles.dateCell}>{formatDate(dealer.createdAt)}</td>
                  <td>
                    <QuickActionsMenu
                      onStartSupport={() => onImpersonate(dealer.userId)}
                      onEditDNS={() => handleEditDNS(dealer)}
                      onRegeneratePages={() => handleRegeneratePages(dealer.id)}
                      onReindexGSC={() => handleReindexGSC(dealer.id)}
                      stripeCustomerId={dealer.stripeCustomerId}
                      hasSubdomain={!!dealer.subdomain}
                      canReindexGSC={
                        ['active', 'cancelled_pending'].includes(dealer.status) &&
                        !!dealer.subdomain &&
                        !dealer.hasPendingReindex
                      }
                      isStartingSupport={isImpersonating === dealer.userId}
                      isRegenerating={regeneratingDealerId === dealer.id}
                      isReindexingGSC={reindexingDealerId === dealer.id}
                    />
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>

        {/* Pagination */}
        <div className={styles.pagination}>
          <div className={styles.paginationInfo}>
            Showing {(pagination.page - 1) * pagination.limit + 1} to{' '}
            {Math.min(pagination.page * pagination.limit, pagination.total)} of {pagination.total}{' '}
            dealers
          </div>
          <div className={styles.paginationControls}>
            <button
              className={styles.pageButton}
              onClick={() => onPageChange(pagination.page - 1)}
              disabled={pagination.page <= 1}
            >
              Previous
            </button>
            <span className={styles.pageIndicator}>
              Page {pagination.page} of {pagination.totalPages}
            </span>
            <button
              className={styles.pageButton}
              onClick={() => onPageChange(pagination.page + 1)}
              disabled={pagination.page >= pagination.totalPages}
            >
              Next
            </button>
          </div>
        </div>
      </div>

      <EditDNSModal
        isOpen={isEditDNSOpen}
        onClose={() => {
          setIsEditDNSOpen(false);
          setEditingDealer(null);
        }}
        dealer={editingDealer}
        onSave={handleSaveSubdomain}
      />

      <StatusChangeModal
        isOpen={isStatusChangeOpen}
        onClose={() => {
          setIsStatusChangeOpen(false);
          setStatusChangeDealer(null);
        }}
        dealer={statusChangeDealer}
        onSave={handleSaveStatus}
      />

      <DealerDetailModal
        isOpen={selectedDealerId !== null}
        onClose={() => setSelectedDealerId(null)}
        dealerId={selectedDealerId}
      />
    </>
  );
}
