import { useState, useRef } from 'react';
import { toast } from 'sonner';
import { Database, Upload, AlertTriangle, Loader2 } from 'lucide-react';
import { api } from '@/api';
import { errMessage } from '@/lib/utils';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import {
  AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent,
  AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle,
} from '@/components/ui/alert-dialog';
import { SectionCard, CountPill, fmt, importErrorState, type SectionCardProps, type ImportErrorState } from './dataShared';

interface ImportSummaryEntry {
  create?: number;
  skip?: number;
  conflict?: number;
}

interface PreviewData {
  import_session_id?: string;
  counts?: Record<string, number>;
  summary?: Record<string, ImportSummaryEntry>;
  metadata?: { exported_at?: string | null };
  source_filename?: string | null;
  warnings?: string[];
}

interface ApplyResult {
  rows_created?: number;
  rows_skipped?: number;
  rows_conflicted?: number;
  rows_errored?: number;
}

interface PreviewState {
  status: 'idle' | 'loading' | 'ready' | 'error';
  data: PreviewData | null;
  error: ImportErrorState | null;
}

interface ApplyState {
  status: 'idle' | 'loading' | 'done' | 'error';
  result: ApplyResult | null;
  error: ImportErrorState | null;
}

export default function ImportMyDataSection({ onHistoryRefresh, cardProps = {} }: {
  onHistoryRefresh?: () => void;
  cardProps?: Partial<SectionCardProps>;
}) {
  const fileRef = useRef<HTMLInputElement>(null);
  const [file, setFile] = useState<File | null>(null);
  const [preview, setPreview] = useState<PreviewState>({ status: 'idle', data: null, error: null });
  const [applyState, setApplyState] = useState<ApplyState>({ status: 'idle', result: null, error: null });
  const [confirmOpen, setConfirmOpen] = useState(false);

  const reset = () => {
    setFile(null);
    setPreview({ status: 'idle', data: null, error: null });
    setApplyState({ status: 'idle', result: null, error: null });
    if (fileRef.current) fileRef.current.value = '';
  };

  const handlePreview = async () => {
    if (!file) {
      toast.error('Choose a SQLite data export first.');
      return;
    }
    setPreview({ status: 'loading', data: null, error: null });
    setApplyState({ status: 'idle', result: null, error: null });
    try {
      const data = await api.previewUserDbImport(file) as PreviewData;
      setPreview({ status: 'ready', data, error: null });
      toast.success('SQLite export preview ready.');
    } catch (err) {
      setPreview({ status: 'error', data: null, error: importErrorState(err, 'SQLite import preview failed.') });
      toast.error(errMessage(err, 'SQLite import preview failed.'));
    }
  };

  const handleApply = () => {
    if (!preview.data?.import_session_id) return;
    setConfirmOpen(true);
  };

  const handleConfirmImport = async () => {
    if (!preview.data?.import_session_id) return;
    setConfirmOpen(false);
    setApplyState({ status: 'loading', result: null, error: null });
    try {
      const result = await api.applyUserDbImport({
        import_session_id: preview.data.import_session_id,
        options: { overwrite: false },
      }) as ApplyResult;
      setApplyState({ status: 'done', result, error: null });
      toast.success('SQLite data import applied.');
      onHistoryRefresh?.();
    } catch (err) {
      setApplyState({ status: 'error', result: null, error: importErrorState(err, 'SQLite import apply failed.') });
      toast.error(errMessage(err, 'SQLite import apply failed.'));
    }
  };

  const counts = preview.data?.counts || {};
  const summary = preview.data?.summary || {};

  return (
    <>
      <SectionCard title="Import My Data Export"
        subtitle="Restore data from a SQLite export created by this app for your account."
        {...cardProps}>
      <div className="px-6 py-5">
        <div className="rounded-lg border border-border/60 bg-muted/25 p-4">
          <div className="flex items-start gap-3">
            <Database className="mt-0.5 h-5 w-5 text-primary shrink-0" />
            <div>
              <p className="text-sm font-medium">Import a SQLite data export created by this app.</p>
              <p className="mt-1 text-xs text-muted-foreground">
                This is not a full system restore. Existing records are skipped by default, and admin/system data is never imported.
              </p>
            </div>
          </div>
        </div>

        <div className="mt-4 flex flex-col gap-3 sm:flex-row sm:items-end">
          <label className="flex-1 space-y-1.5">
            <span className="text-xs font-medium text-muted-foreground">SQLite export file</span>
            <Input
              ref={fileRef}
              type="file"
              accept=".sqlite,.db,application/octet-stream,application/x-sqlite3,application/vnd.sqlite3"
              onChange={e => {
                setFile(e.target.files?.[0] || null);
                setPreview({ status: 'idle', data: null, error: null });
                setApplyState({ status: 'idle', result: null, error: null });
              }}
            />
          </label>
          <div className="flex gap-2">
            <Button size="sm" variant="outline" type="button" onClick={reset}>
              Clear
            </Button>
            <Button size="sm" type="button" disabled={!file || preview.status === 'loading'} onClick={handlePreview}>
              {preview.status === 'loading'
                ? <><Loader2 className="h-3.5 w-3.5 mr-1.5 animate-spin" />Previewing…</>
                : <><Upload className="h-3.5 w-3.5 mr-1.5" />Preview</>}
            </Button>
          </div>
        </div>

        {preview.status === 'error' && (
          <div className="mt-4 rounded-lg border border-destructive/30 bg-destructive/10 p-3 text-sm text-destructive">
            <AlertTriangle className="inline h-4 w-4 mr-1.5" />
            {preview.error?.message || 'SQLite import preview failed.'}
            {(preview.error?.details?.length ?? 0) > 0 && (
              <ul className="mt-2 list-disc pl-5 text-xs">
                {preview.error?.details.map((d, i) => {
                  const dd = d as { message?: string; table?: string };
                  return <li key={i}>{dd.message || dd.table || JSON.stringify(d)}</li>;
                })}
              </ul>
            )}
          </div>
        )}

        {preview.status === 'ready' && preview.data && (
          <div className="mt-4 space-y-4">
            <div className="rounded-lg border border-border/60 bg-background/50 p-4">
              <div className="flex items-start justify-between gap-3">
                <div>
                  <p className="text-sm font-medium">Preview ready</p>
                  <p className="mt-1 text-xs text-muted-foreground">
                    Exported {fmt(preview.data.metadata?.exported_at)} · {preview.data.source_filename || 'SQLite export'}
                  </p>
                </div>
                <span className="rounded-full border border-border bg-muted px-2 py-0.5 text-[10px] font-semibold uppercase text-muted-foreground">
                  User data only
                </span>
              </div>
              <div className="mt-4 grid gap-2 sm:grid-cols-2 xl:grid-cols-5">
                <CountPill label="Bills" value={counts.bills} />
                <CountPill label="Categories" value={counts.categories} />
                <CountPill label="Payments" value={counts.payments} />
                <CountPill label="Monthly" value={counts.monthly_bill_state} />
                <CountPill label="Notes" value={counts.notes} />
              </div>
              <div className="mt-4 grid gap-2 sm:grid-cols-2">
                {Object.entries(summary).filter(([, v]) => v && typeof v === 'object').map(([key, value]) => (
                  <div key={key} className="rounded-lg border border-border/50 bg-muted/20 px-3 py-2 text-xs">
                    <p className="font-semibold capitalize">{key.replace(/_/g, ' ')}</p>
                    <p className="mt-1 text-muted-foreground">
                      create {value.create || 0} · skip {value.skip || 0} · conflict {value.conflict || 0}
                    </p>
                  </div>
                ))}
              </div>
              {(preview.data.warnings?.length ?? 0) > 0 && (
                <div className="mt-4 space-y-1">
                  {preview.data.warnings?.map((warning, i) => (
                    <p key={i} className="text-xs text-amber-600 dark:text-amber-400">
                      <AlertTriangle className="mr-1 inline h-3.5 w-3.5" />{warning}
                    </p>
                  ))}
                </div>
              )}
            </div>

            <div className="flex items-center justify-between gap-3">
              <p className="text-xs text-muted-foreground">Review the preview before applying. Nothing is imported until you confirm.</p>
              <Button size="sm" type="button" disabled={applyState.status === 'loading'} onClick={handleApply}>
                {applyState.status === 'loading'
                  ? <><Loader2 className="h-3.5 w-3.5 mr-1.5 animate-spin" />Applying…</>
                  : 'Apply Import'}
              </Button>
            </div>
          </div>
        )}

        {applyState.status === 'done' && applyState.result && (
          <div className="mt-4 rounded-lg border border-emerald-500/30 bg-emerald-500/5 p-4">
            <p className="text-sm font-medium text-emerald-600">SQLite import applied</p>
            <div className="mt-3 grid grid-cols-2 gap-2 text-xs sm:grid-cols-4">
              <CountPill label="Created" value={applyState.result.rows_created} />
              <CountPill label="Skipped" value={applyState.result.rows_skipped} />
              <CountPill label="Conflicts" value={applyState.result.rows_conflicted} />
              <CountPill label="Errors" value={applyState.result.rows_errored} />
            </div>
          </div>
        )}

        {applyState.status === 'error' && (
          <div className="mt-4 rounded-lg border border-destructive/30 bg-destructive/10 p-3 text-sm text-destructive">
            <AlertTriangle className="inline h-4 w-4 mr-1.5" />{applyState.error?.message || 'SQLite import apply failed.'}
          </div>
        )}
      </div>
    </SectionCard>
    {/* Import confirmation dialog */}
    <AlertDialog open={confirmOpen} onOpenChange={setConfirmOpen}>
      <AlertDialogContent>
        <AlertDialogHeader>
          <AlertDialogTitle>Import SQLite data export?</AlertDialogTitle>
          <AlertDialogDescription>
            Import this SQLite data export into your account? Existing records will be skipped by default.
          </AlertDialogDescription>
        </AlertDialogHeader>
        <AlertDialogFooter>
          <AlertDialogCancel>Cancel</AlertDialogCancel>
          <AlertDialogAction onClick={handleConfirmImport}>
            Confirm Import
          </AlertDialogAction>
        </AlertDialogFooter>
      </AlertDialogContent>
    </AlertDialog>
    </>
  );
}
