'use client';

import { useEffect, useState } from 'react';
import { toast } from 'sonner';
import { PageHeader } from '@/components/navigation/page-header';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';
import { Skeleton } from '@/components/ui/skeleton';
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
import {
  Command,
  CommandEmpty,
  CommandGroup,
  CommandInput,
  CommandItem,
  CommandList,
} from '@/components/ui/command';
import { AlertTriangle, Check, CheckCircle2, ChevronsUpDown, Loader2 } from 'lucide-react';
import DataTable, { type Column } from '@/components/admin/DataTable';
import DetailModal from '@/components/admin/DetailModal';
import { cn } from '@/lib/utils';

interface Pax8CompanyListItem {
  id: string;
  name: string;
  status: string | null;
  city: string | null;
  stateOrProvince: string | null;
  country: string | null;
  autotaskCompanyId: number | null;
  matchConfidence: number | null;
  matchMethod: string | null;
  matchedCompanyName: string | null;
  activeSubscriptionCount: number;
}

interface ReviewCandidate {
  companyId: number;
  companyName: string | null;
  confidence: string | null;
}

interface CompanyReview {
  id: string;
  detectedAt: string;
  pax8CompanyId: string;
  pax8CompanyName: string;
  candidates: ReviewCandidate[];
}

interface ManualCompanyOption {
  id: number;
  company_name: string;
}

function formatConfidence(confidence: string | null): string | null {
  if (!confidence) return null;
  const n = parseFloat(confidence);
  if (Number.isNaN(n)) return confidence;
  return `${Math.round(n * 100)}%`;
}

// Maps DataTable column keys (what the table's onSort callback reports) to
// the /api/pax8/companies `sort` query values (see 14-01-SUMMARY.md).
const SORT_KEY_MAP: Record<string, string> = {
  name: 'name',
  matched: 'match',
  activeSubscriptionCount: 'subscriptions',
  location: 'city',
};

const PAGE_SIZE = 25;

export default function Pax8Page() {
  const [activeTab, setActiveTab] = useState<'companies' | 'needs-review'>('companies');

  const [companies, setCompanies] = useState<Pax8CompanyListItem[]>([]);
  const [totalCount, setTotalCount] = useState(0);
  const [page, setPage] = useState(1);
  const [isLoading, setIsLoading] = useState(false);
  const [sortColumn, setSortColumn] = useState<string | undefined>(undefined);
  const [sortOrder, setSortOrder] = useState<'asc' | 'desc' | undefined>(undefined);
  const [searchQuery, setSearchQuery] = useState<string | undefined>(undefined);

  const [selectedCompany, setSelectedCompany] = useState<Record<string, any> | null>(null);
  const [modalOpen, setModalOpen] = useState(false);

  // Needs Review tab state
  const [reviews, setReviews] = useState<CompanyReview[] | null>(null);
  const [reviewTotal, setReviewTotal] = useState(0);
  const [reviewError, setReviewError] = useState<string | null>(null);
  const [resolving, setResolving] = useState<string | null>(null);
  const [allCompanies, setAllCompanies] = useState<ManualCompanyOption[] | null>(null);
  const [companiesLoading, setCompaniesLoading] = useState(false);
  const [selectedManualCompany, setSelectedManualCompany] = useState<
    Record<string, ManualCompanyOption>
  >({});
  const [openPopoverId, setOpenPopoverId] = useState<string | null>(null);

  const fetchCompanies = async (
    currentPage: number,
    search?: string,
    sortBy?: string,
    order?: 'asc' | 'desc'
  ) => {
    setIsLoading(true);
    try {
      const offset = (currentPage - 1) * PAGE_SIZE;
      const params = new URLSearchParams({ limit: String(PAGE_SIZE), offset: String(offset) });
      if (search) params.append('search', search);
      if (sortBy) params.append('sort', SORT_KEY_MAP[sortBy] ?? sortBy);
      if (order) params.append('order', order);

      const res = await fetch(`/api/pax8/companies?${params}`);
      const data = await res.json();
      setCompanies(data.items ?? []);
      setTotalCount(data.total ?? 0);
    } catch (err) {
      console.error('Failed to fetch PAX8 companies:', err);
    } finally {
      setIsLoading(false);
    }
  };

  useEffect(() => {
    fetchCompanies(page, searchQuery, sortColumn, sortOrder);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [page]);

  const handleSort = (column: string, direction: 'asc' | 'desc') => {
    setSortColumn(column);
    setSortOrder(direction);
    setPage(1);
    fetchCompanies(1, searchQuery, column, direction);
  };

  const handleSearch = (query: string) => {
    setSearchQuery(query);
    setPage(1);
    fetchCompanies(1, query, sortColumn, sortOrder);
  };

  const handlePageChange = (nextPage: number) => {
    setPage(nextPage);
    fetchCompanies(nextPage, searchQuery, sortColumn, sortOrder);
  };

  async function loadReviews(): Promise<void> {
    setReviewError(null);
    setReviews(null);
    try {
      const res = await fetch('/api/pax8/company-matches?limit=100');
      if (!res.ok) {
        const data = (await res.json().catch(() => ({}))) as { error?: string };
        throw new Error(data.error ?? `Request failed: ${res.status}`);
      }
      const data = (await res.json()) as { items: CompanyReview[]; total: number };
      setReviews(data.items);
      setReviewTotal(data.total);
    } catch (err) {
      setReviewError(err instanceof Error ? err.message : 'Unknown error');
    }
  }

  async function ensureCompaniesLoaded(): Promise<void> {
    if (allCompanies !== null || companiesLoading) return;
    setCompaniesLoading(true);
    try {
      const res = await fetch('/api/data/companies-list');
      if (!res.ok) throw new Error(`Request failed: ${res.status}`);
      const data = (await res.json()) as ManualCompanyOption[];
      setAllCompanies(data);
    } catch (err) {
      console.error('Failed to fetch companies list:', err);
    } finally {
      setCompaniesLoading(false);
    }
  }

  // Fetch the review queue + manual-search company list on first activation
  // of the Needs Review tab.
  useEffect(() => {
    if (activeTab !== 'needs-review') return;
    if (reviews === null) void loadReviews();
    void ensureCompaniesLoaded();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [activeTab]);

  async function resolve(reviewId: string, companyId: number, companyName: string): Promise<void> {
    const key = `${reviewId}:${companyId}`;
    setResolving(key);
    try {
      const res = await fetch(`/api/pax8/company-matches/${reviewId}/resolve`, {
        method: 'POST',
        headers: { 'content-type': 'application/json' },
        body: JSON.stringify({ companyId }),
      });
      const data = (await res.json().catch(() => ({}))) as { error?: string };
      if (!res.ok) throw new Error(data.error ?? `Request failed: ${res.status}`);
      toast.success(`Linked to ${companyName}`);
      setReviews((prev) => prev?.filter((r) => r.id !== reviewId) ?? null);
      setReviewTotal((t) => Math.max(0, t - 1));
      setSelectedManualCompany((prev) => {
        const next = { ...prev };
        delete next[reviewId];
        return next;
      });
    } catch (err) {
      toast.error(err instanceof Error ? err.message : 'Resolve failed');
    } finally {
      setResolving(null);
    }
  }

  // Fetch-then-open: keeps the loading indicator on the DataTable (the row's
  // parent) rather than inside an already-open, empty DetailModal.
  const handleRowClick = async (row: Pax8CompanyListItem) => {
    setIsLoading(true);
    try {
      const res = await fetch(`/api/pax8/companies/${row.id}`);
      const data = await res.json();
      setSelectedCompany({
        ...data.company,
        subscriptions: data.subscriptions,
        costTotal: data.costTotal,
      });
      setModalOpen(true);
    } catch (err) {
      console.error('Failed to fetch PAX8 company detail:', err);
    } finally {
      setIsLoading(false);
    }
  };

  const columns: Column<Pax8CompanyListItem>[] = [
    {
      key: 'name',
      label: 'Name',
      sortable: true,
      render: (value: string) => <span className="font-medium">{value}</span>,
    },
    {
      key: 'matched',
      label: 'Matched Company',
      sortable: true,
      render: (_value, row) =>
        row.matchedCompanyName ? (
          <span className="text-primary hover:underline">{row.matchedCompanyName}</span>
        ) : (
          <Badge variant="secondary">Unmatched</Badge>
        ),
    },
    {
      key: 'activeSubscriptionCount',
      label: 'Subs',
      sortable: true,
      render: (value: number) => <span className="font-mono tabular-nums">{value ?? 0}</span>,
    },
    {
      key: 'location',
      label: 'Location',
      sortable: true,
      render: (_value, row) => {
        const parts = [row.city, row.stateOrProvince, row.country].filter(Boolean);
        return parts.length > 0 ? (
          parts.join(', ')
        ) : (
          <span className="text-muted-foreground">—</span>
        );
      },
    },
  ];

  return (
    <>
      <PageHeader
        title="PAX8"
        description="PAX8 companies, subscriptions, and cost breakdown"
        breadcrumbs={[{ label: 'PAX8' }]}
        accent
      />
      <div className="container mx-auto px-6 py-6 space-y-6">
        <Tabs
          value={activeTab}
          onValueChange={(v) => setActiveTab(v as 'companies' | 'needs-review')}
          className="space-y-6"
        >
          <TabsList>
            <TabsTrigger value="companies">Companies</TabsTrigger>
            <TabsTrigger value="needs-review" className="gap-1.5">
              Needs Review
              {reviewTotal > 0 && (
                <span className="ml-1 rounded-full bg-blue-500/20 text-blue-600 text-xs px-1.5 py-0.5 font-medium">
                  {reviewTotal}
                </span>
              )}
            </TabsTrigger>
          </TabsList>

          <TabsContent value="companies" className="space-y-4">
            <DataTable
              columns={columns}
              data={companies}
              totalCount={totalCount}
              page={page}
              pageSize={PAGE_SIZE}
              onPageChange={handlePageChange}
              onSort={handleSort}
              onSearch={handleSearch}
              onRowClick={handleRowClick}
              isLoading={isLoading}
              emptyTitle="No PAX8 companies synced yet"
              emptyDescription="Run the PAX8 sync from /admin/integrations, then refresh this page."
            />
          </TabsContent>

          <TabsContent value="needs-review" className="space-y-4">
            {reviewError && (
              <Alert variant="destructive">
                <AlertTitle>Couldn&apos;t load PAX8 data</AlertTitle>
                <AlertDescription>
                  Check your connection and try again, or visit /admin/integrations if PAX8
                  sync is disabled.
                </AlertDescription>
              </Alert>
            )}

            {reviews === null && !reviewError && (
              <div className="space-y-2">
                <Skeleton className="h-32 w-full" />
                <Skeleton className="h-32 w-full" />
                <Skeleton className="h-32 w-full" />
              </div>
            )}

            {reviews !== null && reviews.length === 0 && !reviewError && (
              <Alert>
                <CheckCircle2 className="size-4" />
                <AlertTitle>No companies need review</AlertTitle>
                <AlertDescription>
                  Every synced PAX8 company is matched to an Autotask company.
                </AlertDescription>
              </Alert>
            )}

            {reviews?.map((review) => (
              <Card key={review.id} className="border-amber-200">
                <CardHeader className="pb-3">
                  <CardTitle className="flex items-center gap-2 text-base font-medium">
                    <AlertTriangle className="size-5 text-amber-500" />
                    {review.pax8CompanyName}
                  </CardTitle>
                </CardHeader>
                <CardContent className="space-y-3">
                  {review.candidates.length > 0 ? (
                    <div className="space-y-2">
                      {review.candidates.map((candidate) => {
                        const key = `${review.id}:${candidate.companyId}`;
                        const isResolving = resolving === key;
                        const confidence = formatConfidence(candidate.confidence);
                        return (
                          <div
                            key={candidate.companyId}
                            className="flex items-center justify-between gap-3 rounded-md border p-3"
                          >
                            <div className="space-y-0.5 min-w-0 flex-1">
                              <div className="text-sm font-medium truncate">
                                {candidate.companyName ?? `Company ${candidate.companyId}`}
                              </div>
                              {confidence && (
                                <Badge variant="outline" className="text-xs font-mono">
                                  {confidence}
                                </Badge>
                              )}
                            </div>
                            <Button
                              size="sm"
                              disabled={isResolving}
                              onClick={() =>
                                void resolve(
                                  review.id,
                                  candidate.companyId,
                                  candidate.companyName ?? `Company ${candidate.companyId}`
                                )
                              }
                            >
                              {isResolving ? (
                                <>
                                  <Loader2 className="size-3 animate-spin mr-1" />
                                  Linking…
                                </>
                              ) : (
                                'Link company'
                              )}
                            </Button>
                          </div>
                        );
                      })}
                    </div>
                  ) : (
                    <Alert>
                      <AlertTitle>No suggested matches</AlertTitle>
                      <AlertDescription>
                        Search manually to link this company to its Autotask counterpart.
                      </AlertDescription>
                    </Alert>
                  )}

                  <div className="flex items-center gap-2 pt-1">
                    <Popover
                      open={openPopoverId === review.id}
                      onOpenChange={(open) => {
                        setOpenPopoverId(open ? review.id : null);
                        if (open) void ensureCompaniesLoaded();
                      }}
                    >
                      <PopoverTrigger asChild>
                        <Button
                          variant="outline"
                          role="combobox"
                          className="flex-1 justify-between font-normal"
                        >
                          {selectedManualCompany[review.id]?.company_name ?? 'Search company…'}
                          <ChevronsUpDown className="size-4 opacity-50" />
                        </Button>
                      </PopoverTrigger>
                      <PopoverContent className="w-[320px] p-0" align="start">
                        <Command>
                          <CommandInput placeholder="Search company…" />
                          <CommandList>
                            <CommandEmpty>
                              {companiesLoading ? 'Loading companies…' : 'No company found.'}
                            </CommandEmpty>
                            <CommandGroup>
                              {(allCompanies ?? []).map((company) => (
                                <CommandItem
                                  key={company.id}
                                  value={company.company_name}
                                  onSelect={() => {
                                    setSelectedManualCompany((prev) => ({
                                      ...prev,
                                      [review.id]: company,
                                    }));
                                    setOpenPopoverId(null);
                                  }}
                                >
                                  <Check
                                    className={cn(
                                      'size-4',
                                      selectedManualCompany[review.id]?.id === company.id
                                        ? 'opacity-100'
                                        : 'opacity-0'
                                    )}
                                  />
                                  {company.company_name}
                                </CommandItem>
                              ))}
                            </CommandGroup>
                          </CommandList>
                        </Command>
                      </PopoverContent>
                    </Popover>
                    <Button
                      disabled={
                        !selectedManualCompany[review.id] ||
                        resolving === `${review.id}:${selectedManualCompany[review.id]?.id}`
                      }
                      onClick={() => {
                        const selected = selectedManualCompany[review.id];
                        if (selected) void resolve(review.id, selected.id, selected.company_name);
                      }}
                    >
                      {resolving === `${review.id}:${selectedManualCompany[review.id]?.id}` ? (
                        <>
                          <Loader2 className="size-3 animate-spin mr-1" />
                          Linking…
                        </>
                      ) : (
                        'Link to selected company'
                      )}
                    </Button>
                  </div>
                </CardContent>
              </Card>
            ))}
          </TabsContent>
        </Tabs>
      </div>

      <DetailModal
        open={modalOpen}
        onOpenChange={setModalOpen}
        kind="pax8_company"
        title={`PAX8: ${selectedCompany?.name ?? ''}`}
        data={selectedCompany}
      />
    </>
  );
}
