'use client';

import { useState, useRef, useCallback } from 'react';
import { ImagePlus, Loader2, X } from 'lucide-react';
import { http } from '@/lib/api';
import { resolveUploadUrl, cn } from '@/lib/utils';
import { Button } from '@/components/ui/button';

export interface ImageUploadProps {
  value?: string;
  onChange: (url: string) => void;
  className?: string;
  /** 提示文字 */
  hint?: string;
}

interface UploadResp {
  url: string;
  filename: string;
}

/**
 * 图片上传组件
 * - 仅接受 jpg/png/jpeg/webp
 * - 单图 2M 上限
 * - 自动 POST /api/admin/upload
 */
export function ImageUpload({
  value,
  onChange,
  className,
  hint = '建议尺寸 1600x900，支持 jpg/png/webp，单图 ≤ 2M',
}: ImageUploadProps) {
  const [uploading, setUploading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const inputRef = useRef<HTMLInputElement>(null);

  const handleFile = useCallback(
    async (file: File) => {
      const allowed = ['image/jpeg', 'image/png', 'image/jpg', 'image/webp'];
      if (!allowed.includes(file.type)) {
        setError('仅支持 jpg/png/jpeg/webp 格式');
        return;
      }
      if (file.size > 2 * 1024 * 1024) {
        setError('单图大小不能超过 2M');
        return;
      }
      setError(null);
      setUploading(true);
      try {
        const form = new FormData();
        form.append('file', file);
        const res = (await http.post<unknown, UploadResp>(
          '/admin/upload',
          form,
          { headers: { 'Content-Type': 'multipart/form-data' } },
        )) as UploadResp;
        onChange(res.url);
      } catch (e) {
        setError((e as Error).message);
      } finally {
        setUploading(false);
      }
    },
    [onChange],
  );

  const onPick = () => inputRef.current?.click();

  const preview = value ? resolveUploadUrl(value) : '';

  return (
    <div className={cn('flex items-start gap-4', className)}>
      <div
        className={cn(
          'relative flex h-28 w-44 items-center justify-center overflow-hidden rounded-md border border-dashed border-gray-300 bg-gray-50',
          !preview && 'cursor-pointer hover:border-brand-400',
        )}
        onClick={!preview ? onPick : undefined}
      >
        {preview ? (
          // eslint-disable-next-line @next/next/no-img-element
          <img src={preview} alt="预览" className="h-full w-full object-cover" />
        ) : uploading ? (
          <Loader2 className="h-6 w-6 animate-spin text-gray-400" />
        ) : (
          <div className="flex flex-col items-center text-gray-400">
            <ImagePlus className="h-6 w-6" />
            <span className="mt-1 text-xs">点击上传</span>
          </div>
        )}
        {preview && (
          <button
            type="button"
            onClick={(e) => {
              e.stopPropagation();
              onChange('');
            }}
            className="absolute right-1 top-1 rounded-full bg-black/60 p-1 text-white hover:bg-black/80"
            aria-label="移除"
          >
            <X className="h-3 w-3" />
          </button>
        )}
      </div>
      <div className="flex-1">
        <input
          ref={inputRef}
          type="file"
          accept="image/jpeg,image/png,image/webp"
          className="hidden"
          onChange={(e) => {
            const f = e.target.files?.[0];
            if (f) void handleFile(f);
            e.target.value = '';
          }}
        />
        <Button type="button" variant="outline" size="sm" onClick={onPick} disabled={uploading}>
          {uploading ? '上传中…' : '选择图片'}
        </Button>
        <p className="mt-2 text-xs text-gray-500">{hint}</p>
        {error && <p className="mt-1 text-xs text-red-600">{error}</p>}
      </div>
    </div>
  );
}
