'use client';

/**
 * Admin Dashboard Page
 *
 * Main dashboard for admin users showing:
 * - Stats overview (total dealers, by tier, by status)
 * - Dealer search and list
 * - Impersonation actions
 */

import React, { useState, useEffect, useCallback, useRef } from 'react';
import Link from 'next/link';
import { StatsCards, TierBreakdown } from '@/components/admin/StatsCards';
import { AtRiskPanel } from '@/components/admin/AtRiskPanel';
import { AtRiskCard } from '@/components/admin/AtRiskCard';
import { DealerSearch, SearchParams } from '@/components/admin/DealerSearch';
import { DealerTable } from '@/components/admin/DealerTable';
import { DealerDetailModal } from '@/components/admin/DealerDetailModal';
import { PlatformAnalyticsCard } from '@/components/admin/PlatformAnalyticsCard';
import { PlatformAnalyticsPanel } from '@/components/admin/PlatformAnalyticsPanel';
import { ToastProvider } from '@/components/ui/Toast';
import { Modal, ModalBody } from '@/components/ui/Modal';
import styles from './page.module.css';

interface Stats {
  totalDealers: number;
  byTier: {
    starter: number;
    growth: number;
    enhanced: number;
    professional: number;
  };
  byStatus: {
    active: number;
    pending: number;
    suspended: number;
    cancelled: number;
    payment_failed: number;
  };
  recentlyCreated: Array<{
    id: string;
    userId: string;
    subdomain: string | null;
    businessName: string | null;
    subscriptionTier: string;
    status: string;
    createdAt: string;
    user: {
      id: string;
      email: string;
      name: string | null;
    };
  }>;
}

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;
  user: {
    id: string;
    email: string;
    name: string | null;
    image: string | null;
    role: string;
  };
}

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

// Debounce hook
function useDebounce<T>(value: T, delay: number): T {
  const [debouncedValue, setDebouncedValue] = useState<T>(value);

  useEffect(() => {
    const timer = setTimeout(() => {
      setDebouncedValue(value);
    }, delay);

    return () => {
      clearTimeout(timer);
    };
  }, [value, delay]);

  return debouncedValue;
}

export default function AdminDashboardPage() {
  // Stats state
  const [stats, setStats] = useState<Stats | null>(null);
  const [statsLoading, setStatsLoading] = useState(true);
  const [statsError, setStatsError] = useState<string | null>(null);

  // Dealers state
  const [dealers, setDealers] = useState<Dealer[]>([]);
  const [pagination, setPagination] = useState<Pagination>({
    page: 1,
    limit: 20,
    total: 0,
    totalPages: 0,
  });
  const [dealersLoading, setDealersLoading] = useState(true);
  const [dealersError, setDealersError] = useState<string | null>(null);

  // Search state
  const [searchParams, setSearchParams] = useState<SearchParams>({
    search: '',
    tier: '',
    status: '',
  });
  // Typed input is debounced (600ms) to avoid hammering the dealers endpoint
  // on every keystroke. Programmatic sets (e.g. from At-Risk Inspect) bypass
  // the debounce via `forcedSearch` so the user doesn't see stale results
  // during the gap before the new query lands.
  const debouncedSearch = useDebounce(searchParams.search, 600);
  const [forcedSearch, setForcedSearch] = useState<string | null>(null);
  const effectiveSearch = forcedSearch ?? debouncedSearch;

  // Dealers section anchor — At-Risk panel scrolls here on Inspect
  const dealersSectionRef = useRef<HTMLElement | null>(null);

  // Sort state
  const [sortBy, setSortBy] = useState<string>('createdAt');
  const [sortOrder, setSortOrder] = useState<'asc' | 'desc'>('desc');

  // Impersonation state
  const [isImpersonating, setIsImpersonating] = useState<string | null>(null);
  const [impersonationError, setImpersonationError] = useState<string | null>(null);

  // At-Risk modal visibility
  const [isAtRiskModalOpen, setIsAtRiskModalOpen] = useState(false);
  // Dealer-detail modal opened directly from the At-Risk panel (stacks over it
  // so the admin can view a dealer and return to the at-risk list).
  const [detailDealerId, setDetailDealerId] = useState<string | null>(null);

  // Platform analytics modal
  const [isPlatformAnalyticsOpen, setIsPlatformAnalyticsOpen] = useState(false);

  // Fetch stats
  useEffect(() => {
    async function fetchStats() {
      try {
        setStatsLoading(true);
        setStatsError(null);

        const response = await fetch('/api/admin/stats');
        const data = await response.json();

        if (!data.success) {
          throw new Error(data.error || 'Failed to fetch stats');
        }

        setStats(data.stats);
      } catch (error) {
        setStatsError(error instanceof Error ? error.message : 'Failed to fetch stats');
      } finally {
        setStatsLoading(false);
      }
    }

    fetchStats();
  }, []);

  // Fetch dealers
  const fetchDealers = useCallback(
    async (page: number = 1) => {
      try {
        setDealersLoading(true);
        setDealersError(null);

        const params = new URLSearchParams({
          page: page.toString(),
          limit: '20',
          sortBy,
          sortOrder,
        });

        if (effectiveSearch) {
          params.set('search', effectiveSearch);
        }
        if (searchParams.tier) {
          params.set('tier', searchParams.tier);
        }
        if (searchParams.status) {
          params.set('status', searchParams.status);
        }

        const response = await fetch(`/api/admin/dealers?${params.toString()}`);
        const data = await response.json();

        if (!data.success) {
          throw new Error(data.error || 'Failed to fetch dealers');
        }

        setDealers(data.dealers);
        setPagination(data.pagination);
      } catch (error) {
        setDealersError(error instanceof Error ? error.message : 'Failed to fetch dealers');
      } finally {
        setDealersLoading(false);
      }
    },
    [effectiveSearch, searchParams.tier, searchParams.status, sortBy, sortOrder]
  );

  // Initial fetch and on search change
  useEffect(() => {
    fetchDealers(1);
  }, [fetchDealers]);

  // Handle search — user-typed input goes through the debounce.
  const handleSearch = useCallback((params: SearchParams) => {
    setSearchParams(params);
    setForcedSearch(null);
  }, []);

  // From the At-Risk panel: filter the dealer table to the chosen dealer and
  // scroll down so the existing table + detail modal handle the triage.
  // Bypasses the 600ms debounce — otherwise the user sees stale results
  // under the scroll until the next debounce tick fires.
  const handleInspect = useCallback((searchValue: string) => {
    setSearchParams({ search: searchValue, tier: '', status: '' });
    setForcedSearch(searchValue);
    dealersSectionRef.current?.scrollIntoView({ behavior: 'smooth', block: 'start' });
  }, []);

  // Handle page change. Clear forcedSearch (the programmatic Inspect bypass)
  // since by the time the user paginates, the debounced search has caught up
  // and the two values agree — keeping forcedSearch live past that point just
  // muddies the two-state semantics.
  const handlePageChange = useCallback(
    (page: number) => {
      setForcedSearch(null);
      fetchDealers(page);
    },
    [fetchDealers]
  );

  // Handle sort change - reset to page 1 when sort changes. Same forcedSearch
  // cleanup as page change.
  const handleSort = useCallback((field: string, order: 'asc' | 'desc') => {
    setForcedSearch(null);
    setSortBy(field);
    setSortOrder(order);
  }, []);

  // Handle impersonation
  const handleImpersonate = useCallback(async (userId: string) => {
    try {
      setIsImpersonating(userId);
      setImpersonationError(null);

      const response = await fetch('/api/admin/impersonate/start', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ targetUserId: userId }),
      });

      const data = await response.json();

      if (!data.success) {
        throw new Error(data.error || 'Failed to start impersonation');
      }

      // Use full page navigation to ensure session is refreshed
      // (client-side router.push would keep stale session data)
      window.location.href = '/dashboard';
    } catch (error) {
      setImpersonationError(error instanceof Error ? error.message : 'Failed to impersonate');
      setIsImpersonating(null);
    }
  }, []);

  return (
    <ToastProvider>
      <div className={styles.container}>
        {/* Admin Tools */}
        <section className={styles.section}>
          <h2 className={styles.sectionTitle}>Admin Tools</h2>
          <div className={styles.adminTools}>
            <Link href="/admin/amsoil-images" className={styles.adminToolCard}>
              <div className={styles.adminToolIcon}>
                <svg
                  width="24"
                  height="24"
                  viewBox="0 0 24 24"
                  fill="none"
                  stroke="currentColor"
                  strokeWidth="2"
                >
                  <rect x="3" y="3" width="18" height="18" rx="2" ry="2" />
                  <circle cx="8.5" cy="8.5" r="1.5" />
                  <polyline points="21 15 16 10 5 21" />
                </svg>
              </div>
              <div className={styles.adminToolInfo}>
                <h3>AMSOIL Images</h3>
                <p>Manage branded images for dealers</p>
              </div>
            </Link>
            <Link href="/admin/resource-guides" className={styles.adminToolCard}>
              <div className={styles.adminToolIcon}>
                <svg
                  width="24"
                  height="24"
                  viewBox="0 0 24 24"
                  fill="none"
                  stroke="currentColor"
                  strokeWidth="2"
                >
                  <path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20" />
                  <path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z" />
                </svg>
              </div>
              <div className={styles.adminToolInfo}>
                <h3>Resource Guides</h3>
                <p>Create and manage dealer resource guides</p>
              </div>
            </Link>
            <Link href="/admin/gsc" className={styles.adminToolCard}>
              <div className={styles.adminToolIcon}>
                <svg
                  width="24"
                  height="24"
                  viewBox="0 0 24 24"
                  fill="none"
                  stroke="currentColor"
                  strokeWidth="2"
                >
                  <circle cx="11" cy="11" r="8" />
                  <line x1="21" y1="21" x2="16.65" y2="16.65" />
                  <line x1="11" y1="8" x2="11" y2="14" />
                  <line x1="8" y1="11" x2="14" y2="11" />
                </svg>
              </div>
              <div className={styles.adminToolInfo}>
                <h3>GSC Indexing</h3>
                <p>Monitor quota usage, queue health, and run backfill</p>
              </div>
            </Link>
            <AtRiskCard onClick={() => setIsAtRiskModalOpen(true)} />
            <PlatformAnalyticsCard onClick={() => setIsPlatformAnalyticsOpen(true)} />
          </div>
        </section>

        {/* Stats Section */}
        <section className={styles.section}>
          {statsError && (
            <div className={styles.error}>
              <p>{statsError}</p>
            </div>
          )}
          {stats && (
            <>
              <StatsCards stats={stats} isLoading={statsLoading} />
              <TierBreakdown stats={stats} />
            </>
          )}
          {statsLoading && !stats && (
            <StatsCards
              stats={{
                totalDealers: 0,
                byTier: { starter: 0, growth: 0, enhanced: 0, professional: 0 },
                byStatus: { active: 0, pending: 0, suspended: 0, cancelled: 0, payment_failed: 0 },
              }}
              isLoading
            />
          )}
        </section>

        {/* Dealers Section */}
        <section className={styles.section} ref={dealersSectionRef}>
          <h2 className={styles.sectionTitle}>Dealers</h2>

          {impersonationError && (
            <div className={styles.error}>
              <p>{impersonationError}</p>
              <button className={styles.dismissButton} onClick={() => setImpersonationError(null)}>
                Dismiss
              </button>
            </div>
          )}

          <DealerSearch
            onSearch={handleSearch}
            isLoading={dealersLoading}
            searchValue={searchParams.search}
          />

          {dealersError && (
            <div className={styles.error}>
              <p>{dealersError}</p>
            </div>
          )}

          <DealerTable
            dealers={dealers}
            pagination={pagination}
            onPageChange={handlePageChange}
            onImpersonate={handleImpersonate}
            onDealerUpdated={() => fetchDealers(pagination.page)}
            isLoading={dealersLoading}
            isImpersonating={isImpersonating}
            sortBy={sortBy}
            sortOrder={sortOrder}
            onSort={handleSort}
          />
        </section>

        <Modal
          isOpen={isAtRiskModalOpen}
          onClose={() => setIsAtRiskModalOpen(false)}
          title="At-Risk Dealers"
          size="wide"
        >
          <ModalBody>
            <AtRiskPanel
              onInspect={(searchValue) => {
                setIsAtRiskModalOpen(false);
                handleInspect(searchValue);
              }}
              onViewDetails={(dealerId) => setDetailDealerId(dealerId)}
            />
          </ModalBody>
        </Modal>

        {/* Detail modal opened from the At-Risk panel — stacks over the
            At-Risk modal so closing it returns to the at-risk list. */}
        <DealerDetailModal
          isOpen={detailDealerId !== null}
          dealerId={detailDealerId}
          onClose={() => setDetailDealerId(null)}
        />
      </div>
      <Modal
        isOpen={isPlatformAnalyticsOpen}
        onClose={() => setIsPlatformAnalyticsOpen(false)}
        size="wide"
        title="Platform Analytics"
      >
        <ModalBody>
          <PlatformAnalyticsPanel />
        </ModalBody>
      </Modal>
    </ToastProvider>
  );
}
