import { useState } from 'react';
import { useTranslation } from 'react-i18next';
import { addMonths, startOfMonth, format } from 'date-fns';
import { Sparkles } from 'lucide-react';
import { trpc } from '@/lib/trpc';
import { Button } from '@/components/ui/button';
import {
  Empty,
  EmptyHeader,
  EmptyMedia,
  EmptyTitle,
  EmptyDescription,
} from '@/components/ui/empty';
import { useNotify } from '@/hooks/useNotify';
import { usePlatform } from '@/lib/platform';
import { FolderLinkCard } from './FolderLinkCard';
import { FolderFileList } from './FolderFileList';
import { FolderUnlinkDialog } from './FolderUnlinkDialog';

interface FilesSectionProps {
  projectId: string;
  folderPath: string | null;
  totalFiles: number;
  lastScannedAt: number | null;
  scanStatus: 'idle' | 'scanning' | 'error' | null;
}

export function FilesSection({
  projectId,
  folderPath,
  totalFiles,
  lastScannedAt,
  scanStatus,
}: FilesSectionProps) {
  const { t } = useTranslation();
  const { notify, notifyError } = useNotify();
  const platform = usePlatform();
  const [unlinkOpen, setUnlinkOpen] = useState(false);
  const utils = trpc.useUtils();

  const chooseFolder = trpc.projectFolders.chooseFolder.useMutation();
  const link = trpc.projectFolders.link.useMutation({
    onSuccess: () => utils.projects.get.invalidate({ id: projectId }),
    onError: (err) => notifyError('errors.error', err),
  });
  const startScan = trpc.projectFolders.startScan.useMutation();

  /** Parse a QUOTA error message from the tRPC FORBIDDEN payload. */
  function handleScanError(err: { message?: string }): void {
    const msg = err.message ?? '';
    if (msg.startsWith('QUOTA:max_files:')) {
      // Backend message format: "Folder has X files; tier 'free' allows max Y."
      // Extract tier and max-count to pass to the i18n key.
      const detail = msg.slice('QUOTA:max_files:'.length);
      const tierMatch = detail.match(/tier '([^']+)'/);
      const countMatch = detail.match(/allows max (\d+)/);
      const tier = tierMatch?.[1] ?? 'your';
      const count = countMatch ? parseInt(countMatch[1], 10) : 0;
      notify('error', 'projects.folder.errors.tooBig', { values: { tier, count } });
      return;
    }
    if (msg.startsWith('QUOTA:monthly_tokens:')) {
      // Compute first day of next month as the reset date.
      const resetDate = format(startOfMonth(addMonths(new Date(), 1)), 'PP');
      notify('error', 'projects.folder.errors.monthlyExhausted', { values: { date: resetDate } });
      return;
    }
    notifyError('errors.error', err);
  }

  const handleChoose = async () => {
    const chosen = await chooseFolder.mutateAsync();
    if (chosen) {
      await link.mutateAsync({ projectId, folderPath: chosen });
      // Kick first scan (fire-and-forget — progress shown via getStatus polling).
      // Quota errors are caught here so we can show localised toasts.
      startScan.mutate({ projectId }, { onError: handleScanError });
    }
  };

  if (!platform.isElectron) {
    return (
      <div className="text-sm text-muted-foreground p-6 text-center">
        {t('projects.folder.webOnlyTooltip')}
      </div>
    );
  }

  if (!folderPath) {
    return (
      <Empty>
        <EmptyHeader>
          <EmptyMedia>
            <Sparkles />
          </EmptyMedia>
          <EmptyTitle>{t('projects.folder.empty.title')}</EmptyTitle>
          <EmptyDescription>{t('projects.folder.empty.description')}</EmptyDescription>
        </EmptyHeader>
        <Button
          onClick={handleChoose}
          disabled={chooseFolder.isPending || link.isPending}
        >
          {t('projects.folder.empty.cta')}
        </Button>
      </Empty>
    );
  }

  return (
    <div className="space-y-4">
      <FolderLinkCard
        projectId={projectId}
        folderPath={folderPath}
        totalFiles={totalFiles}
        lastScannedAt={lastScannedAt}
        scanStatus={scanStatus}
        onUnlinkRequested={() => setUnlinkOpen(true)}
      />
      <FolderFileList projectId={projectId} />
      <FolderUnlinkDialog
        projectId={projectId}
        open={unlinkOpen}
        onOpenChange={setUnlinkOpen}
      />
    </div>
  );
}
