import { useState, type ComponentType } from 'react';
import { toast } from 'sonner';
import { Database, Download, FileSpreadsheet, FileJson, AlertTriangle, CheckCircle2, XCircle, Loader2 } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { cn, errMessage } from '@/lib/utils';
import { downloadFile } from '@/lib/download';
import { SectionCard, type SectionCardProps } from './dataShared';

function ExportCard({ icon: Icon, title, description, filename, endpoint }: {
  icon: ComponentType<{ className?: string }>;
  title: string;
  description: string;
  filename: string;
  endpoint: string;
}) {
  const [loading, setLoading] = useState(false);
  const handleDownload = async () => {
    setLoading(true);
    try {
      await downloadFile(endpoint, filename);
      toast.success(`${title} downloaded.`);
    } catch (err) {
      toast.error(errMessage(err, 'Download failed.'));
    } finally {
      setLoading(false);
    }
  };
  return (
    <div className="flex items-start justify-between gap-6 px-6 py-5">
      <div className="flex min-w-0 flex-1 items-start gap-4">
        <div className="mt-0.5 flex h-9 w-9 shrink-0 items-center justify-center rounded-lg bg-primary/10">
          <Icon className="h-5 w-5 text-primary" />
        </div>
        <div className="min-w-0 flex-1">
          <p className="mb-0.5 text-sm font-medium">{title}</p>
          <p className="text-xs text-muted-foreground">{description}</p>
        </div>
      </div>
      <div className="shrink-0 pt-0.5">
        <Button size="sm" variant="outline" disabled={loading} onClick={handleDownload}>
          {loading ? <><Loader2 className="mr-1.5 h-3.5 w-3.5 animate-spin" />Downloading…</>
            : <><Download className="mr-1.5 h-3.5 w-3.5" />Download</>}
        </Button>
      </div>
    </div>
  );
}

// Filtered payments export: current year by default, or a custom date range, as CSV or JSON.
function PaymentsExport() {
  const [from, setFrom] = useState('');
  const [to, setTo] = useState('');
  const [format, setFormat] = useState('csv');
  const [loading, setLoading] = useState(false);

  const handle = async () => {
    if ((from && !to) || (!from && to)) { toast.error('Enter both From and To dates, or leave both empty.'); return; }
    if (from && to && from > to) { toast.error('“From” must be on or before “To”.'); return; }
    const params = new URLSearchParams({ format });
    if (from && to) { params.set('from', from); params.set('to', to); }
    setLoading(true);
    try {
      await downloadFile(`/api/export?${params.toString()}`, `bills.${format === 'json' ? 'json' : 'csv'}`);
      toast.success('Payments exported.');
    } catch (err) {
      toast.error(errMessage(err, 'Export failed.'));
    } finally {
      setLoading(false);
    }
  };

  return (
    <div className="px-6 py-5">
      <div className="rounded-lg border border-border/60 bg-muted/25 p-4">
        <p className="text-sm font-medium">Payments export</p>
        <p className="mt-0.5 text-xs text-muted-foreground">Just your payment records — filter by date and choose a format. Leave dates empty for the current year.</p>
        <div className="mt-3 flex flex-wrap items-end gap-3">
          <div>
            <Label htmlFor="pe-from" className="text-xs">From</Label>
            <Input id="pe-from" type="date" value={from} onChange={e => setFrom(e.target.value)} className="mt-1 h-9 w-[9.5rem]" />
          </div>
          <div>
            <Label htmlFor="pe-to" className="text-xs">To</Label>
            <Input id="pe-to" type="date" value={to} onChange={e => setTo(e.target.value)} className="mt-1 h-9 w-[9.5rem]" />
          </div>
          <div>
            <span className="block text-xs text-muted-foreground">Format</span>
            <div className="mt-1 inline-flex rounded-lg border border-border/60 p-0.5" role="group" aria-label="Export format">
              {['csv', 'json'].map(f => (
                <button
                  key={f}
                  type="button"
                  aria-pressed={format === f}
                  onClick={() => setFormat(f)}
                  className={cn('rounded-md px-2.5 py-1 text-xs font-medium transition-colors',
                    format === f ? 'bg-primary text-primary-foreground' : 'text-muted-foreground hover:text-foreground')}
                >
                  {f.toUpperCase()}
                </button>
              ))}
            </div>
          </div>
          <Button size="sm" className="h-9 gap-1.5" disabled={loading} onClick={handle}>
            {loading ? <Loader2 className="h-3.5 w-3.5 animate-spin" /> : <Download className="h-3.5 w-3.5" />}
            Export
          </Button>
        </div>
      </div>
    </div>
  );
}

export default function DownloadMyDataSection({ cardProps = {} }: { cardProps?: Partial<SectionCardProps> }) {
  return (
    <SectionCard
      title="Download My Data"
      subtitle="Export your bill tracker data for your own records. These exports include only your data — not a full system backup."
      {...cardProps}
    >
      <ExportCard icon={Database} title="SQLite backup"
        description="A portable SQLite database with all of your bill tracker data — the format used to restore a backup."
        filename="bill-tracker-user-export.sqlite" endpoint="/api/export/user-db" />
      <ExportCard icon={FileSpreadsheet} title="Excel databook"
        description="An Excel workbook with sheets for bills, payments, categories, monthly state, and summary data."
        filename="bill-tracker-databook.xlsx" endpoint="/api/export/user-excel" />
      <ExportCard icon={FileJson} title="JSON export"
        description="Your full data as portable JSON — handy for scripting, backups, or moving between tools."
        filename="bill-tracker-user-export.json" endpoint="/api/export/user-json" />
      <PaymentsExport />
      <div className="mx-6 mt-2 flex items-start gap-2.5 rounded-md border border-amber-200 bg-amber-50 px-6 py-3 dark:border-amber-800/40 dark:bg-amber-950/30">
        <AlertTriangle className="mt-0.5 h-4 w-4 shrink-0 text-amber-600 dark:text-amber-400" />
        <p className="text-xs text-amber-700 dark:text-amber-300">Exports may contain sensitive account metadata (website URLs, usernames, account info). Store exported files securely and avoid sharing them unencrypted.</p>
      </div>
      <div className="grid grid-cols-1 gap-3 px-6 py-5 sm:grid-cols-2">
        <div className="rounded-lg border border-border/60 bg-muted/40 p-4">
          <p className="mb-2.5 text-[10px] font-bold uppercase tracking-widest text-muted-foreground">What's included</p>
          <ul className="space-y-1.5">
            {['Bills','Payments','Categories','Monthly bill state','Monthly starting amounts','History ranges','Notes','Export metadata'].map(i => (
              <li key={i} className="flex items-center gap-2 text-xs text-foreground/80">
                <CheckCircle2 className="h-3.5 w-3.5 shrink-0 text-emerald-500" />{i}
              </li>
            ))}
          </ul>
        </div>
        <div className="rounded-lg border border-border/60 bg-muted/40 p-4">
          <p className="mb-2.5 text-[10px] font-bold uppercase tracking-widest text-muted-foreground">What's not included</p>
          <ul className="space-y-1.5">
            {['Passwords','Sessions','Admin settings','Server configuration',"Other users' data",'Full system backup files'].map(i => (
              <li key={i} className="flex items-center gap-2 text-xs text-muted-foreground">
                <XCircle className="h-3.5 w-3.5 shrink-0 text-muted-foreground" />{i}
              </li>
            ))}
          </ul>
        </div>
      </div>
    </SectionCard>
  );
}
