import { useRef, useState } from 'react';
import { AlertCircle, Download, FileText, LoaderCircle, Upload } from 'lucide-react';

import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';

const ACCEPTED_ATTACHMENTS = '.pdf,.xlsx,.xls,.png,.jpg,.jpeg,.webp';

function fileSizeText(size: number): string {
  if (size < 1024) return `${size} B`;
  if (size < 1024 * 1024) return `${(size / 1024).toFixed(1)} KB`;
  return `${(size / 1024 / 1024).toFixed(1)} MB`;
}

function filenameFromDisposition(disposition: string | null): string {
  if (!disposition) {
    return `采购物料清单-${new Date().toISOString().slice(0, 10)}.xlsx`;
  }

  const encoded = disposition.match(/filename\*=UTF-8''([^;]+)/i)?.[1];
  if (encoded) {
    return decodeURIComponent(encoded.replace(/^"|"$/g, ''));
  }

  const quoted = disposition.match(/filename="?([^";]+)"?/i)?.[1];
  return quoted || `采购物料清单-${new Date().toISOString().slice(0, 10)}.xlsx`;
}

async function readErrorMessage(response: Response): Promise<string> {
  try {
    const body = await response.json() as { error?: unknown; message?: unknown };
    return String(body.error || body.message || `导出失败 (${response.status})`);
  } catch {
    return `导出失败 (${response.status})`;
  }
}

export default function ProcurementListReview() {
  const inputRef = useRef<HTMLInputElement | null>(null);
  const [files, setFiles] = useState<File[]>([]);
  const [isProcessing, setIsProcessing] = useState(false);
  const [error, setError] = useState('');
  const [lastFilename, setLastFilename] = useState('');

  async function handleExport() {
    if (files.length === 0 || isProcessing) {
      return;
    }

    setIsProcessing(true);
    setError('');
    setLastFilename('');

    try {
      const formData = new FormData();
      files.forEach((file) => formData.append('files', file));

      const response = await fetch('/api/procurement-list/export', {
        method: 'POST',
        body: formData,
      });
      if (!response.ok) {
        throw new Error(await readErrorMessage(response));
      }

      const blob = await response.blob();
      const filename = filenameFromDisposition(response.headers.get('content-disposition'));
      const url = URL.createObjectURL(blob);
      const link = document.createElement('a');
      link.href = url;
      link.download = filename;
      document.body.appendChild(link);
      link.click();
      link.remove();
      URL.revokeObjectURL(url);
      setLastFilename(filename);
    } catch (caught) {
      setError(caught instanceof Error ? caught.message : String(caught));
    } finally {
      setIsProcessing(false);
    }
  }

  return (
    <div className="min-h-screen bg-background p-6">
      <div className="mx-auto flex max-w-5xl flex-col gap-6">
        <header className="flex flex-col gap-2">
          <h1 className="text-3xl font-bold text-foreground">清单梳理</h1>
          <p className="text-base text-muted-foreground">在线生成采购物料清单 Excel</p>
        </header>

        <section className="rounded-lg border bg-card p-6 shadow-sm">
          <div className="grid gap-5">
            <div className="grid gap-2">
              <Label htmlFor="procurement-list-files">上传附件</Label>
              <Input
                ref={inputRef}
                id="procurement-list-files"
                aria-label="上传附件"
                type="file"
                multiple
                accept={ACCEPTED_ATTACHMENTS}
                onChange={(event) => {
                  setFiles(Array.from(event.target.files ?? []));
                  setError('');
                  setLastFilename('');
                }}
              />
            </div>

            <div className="flex flex-wrap items-center gap-3">
              <Button onClick={handleExport} disabled={files.length === 0 || isProcessing}>
                {isProcessing ? <LoaderCircle className="mr-2 h-4 w-4 animate-spin" /> : <Download className="mr-2 h-4 w-4" />}
                {isProcessing ? '处理中' : '生成 Excel'}
              </Button>
              <Button
                type="button"
                variant="outline"
                onClick={() => {
                  setFiles([]);
                  setError('');
                  setLastFilename('');
                  if (inputRef.current) {
                    inputRef.current.value = '';
                  }
                }}
                disabled={isProcessing || files.length === 0}
              >
                清空
              </Button>
              <Badge variant="secondary">PDF / Excel / 图片</Badge>
            </div>

            {error && (
              <div className="flex items-start gap-2 rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive">
                <AlertCircle className="mt-0.5 h-4 w-4 shrink-0" />
                <span>{error}</span>
              </div>
            )}

            {lastFilename && (
              <div className="flex items-start gap-2 rounded-md border border-emerald-200 bg-emerald-50 px-3 py-2 text-sm text-emerald-800">
                <Download className="mt-0.5 h-4 w-4 shrink-0" />
                <span>已生成 {lastFilename}</span>
              </div>
            )}
          </div>
        </section>

        <section className="rounded-lg border bg-card p-6 shadow-sm">
          <div className="mb-4 flex items-center justify-between gap-3">
            <h2 className="text-lg font-semibold text-foreground">待处理附件</h2>
            <span className="text-sm text-muted-foreground">{files.length} 个文件</span>
          </div>
          {files.length === 0 ? (
            <div className="flex min-h-36 flex-col items-center justify-center gap-3 rounded-md border border-dashed text-muted-foreground">
              <Upload className="h-8 w-8" />
              <span>选择 PDF、Excel 或图片后生成 Excel</span>
            </div>
          ) : (
            <div className="divide-y rounded-md border">
              {files.map((file) => (
                <div key={`${file.name}-${file.size}-${file.lastModified}`} className="flex items-center justify-between gap-4 px-4 py-3">
                  <div className="flex min-w-0 items-center gap-3">
                    <FileText className="h-5 w-5 shrink-0 text-muted-foreground" />
                    <div className="min-w-0">
                      <p className="truncate font-medium text-foreground">{file.name}</p>
                      <p className="text-sm text-muted-foreground">{file.type || '未知类型'} · {fileSizeText(file.size)}</p>
                    </div>
                  </div>
                  <Badge variant="outline">已选择</Badge>
                </div>
              ))}
            </div>
          )}
        </section>
      </div>
    </div>
  );
}
