import { useEffect, useRef, useState } from 'react';
import { motion, AnimatePresence } from 'motion/react';
import { MessageCircleHeart, X, ChevronRight, ChevronLeft, Check, Sparkles, ImagePlus, Loader2, Inbox } from 'lucide-react';
import { fetchJson } from '../auth/api-client';
import FeedbackHistoryDrawer from './FeedbackHistoryDrawer';

const MAX_SCREENSHOTS = 6;
const MAX_IMG_SIZE_MB = 5;

interface UploadedImg {
  url: string;
  thumbDataUrl: string;
}

async function uploadImage(file: File): Promise<string> {
  const fd = new FormData();
  fd.append('file', file);
  const token = sessionStorage.getItem('bi_jwt');
  const res = await fetch('/api/feedback/upload', {
    method: 'POST',
    headers: token ? { Authorization: `Bearer ${token}` } : {},
    body: fd,
  });
  const json = await res.json();
  if (!res.ok || !json.ok) throw new Error(json.message || `上传失败 (${res.status})`);
  return json.url as string;
}

function readAsDataUrl(file: File): Promise<string> {
  return new Promise((resolve, reject) => {
    const r = new FileReader();
    r.onload = () => resolve(String(r.result || ''));
    r.onerror = reject;
    r.readAsDataURL(file);
  });
}

type FeedbackType = 'dimension' | 'bug' | 'ux' | 'other';

const TYPE_OPTIONS: { key: FeedbackType; emoji: string; label: string; sub: string; color: string }[] = [
  { key: 'dimension', emoji: '💡', label: '想看新的统计维度', sub: '比如按 XX 维度分组', color: 'from-amber-50 to-orange-50 border-amber-100' },
  { key: 'bug',       emoji: '🐛', label: '报告一个 bug',     sub: '哪里看着不对劲',   color: 'from-rose-50 to-red-50 border-rose-100' },
  { key: 'ux',        emoji: '🎨', label: '界面 / 体验建议', sub: '哪里能更顺手',     color: 'from-violet-50 to-fuchsia-50 border-violet-100' },
  { key: 'other',     emoji: '📝', label: '其他想法',         sub: '欢迎随便聊聊',     color: 'from-slate-50 to-blue-50 border-slate-100' },
];

const MODULE_LABELS: Record<string, string> = {
  assets: '资产管理',
  mileage: '里程管理',
  energy: '能源管理',
  scheduling: '智能调度',
  ele: '充电导入',
  '': '通用',
};

function detectModule(): string {
  const hash = (window.location.hash || '').slice(1);
  const path = window.location.pathname;
  if (path.includes('/ele/')) return 'ele';
  if (hash.includes('ele')) return 'ele';
  if (hash.startsWith('/')) return hash.split('/')[1] || '';
  return hash || '';
}

interface Props {
  /** 显式覆盖当前模块（否则自动从 URL 检测） */
  module?: string;
}

export default function FeedbackFab({ module: moduleProp }: Props = {}) {
  const [open, setOpen] = useState(false);
  const [historyOpen, setHistoryOpen] = useState(false);
  const [menuOpen, setMenuOpen] = useState(false);
  const [step, setStep] = useState<1 | 2 | 3 | 4>(1);
  const [type, setType] = useState<FeedbackType | null>(null);
  const [mod, setMod] = useState<string>('');
  const [content, setContent] = useState('');
  const [contact, setContact] = useState('');
  const [shots, setShots] = useState<UploadedImg[]>([]);
  const [uploading, setUploading] = useState(false);
  const [submitting, setSubmitting] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const taRef = useRef<HTMLTextAreaElement>(null);
  const fileRef = useRef<HTMLInputElement>(null);

  const addFiles = async (files: FileList | File[]) => {
    const list = Array.from(files).filter(f => f.type.startsWith('image/'));
    if (list.length === 0) return;
    setError(null);
    setUploading(true);
    try {
      for (const f of list) {
        if (shots.length >= MAX_SCREENSHOTS) break;
        if (f.size > MAX_IMG_SIZE_MB * 1024 * 1024) {
          setError(`「${f.name}」超过 ${MAX_IMG_SIZE_MB}MB`);
          continue;
        }
        const thumbDataUrl = await readAsDataUrl(f);
        const url = await uploadImage(f);
        setShots(prev => prev.length >= MAX_SCREENSHOTS ? prev : [...prev, { url, thumbDataUrl }]);
      }
    } catch (e) {
      setError(e instanceof Error ? e.message : String(e));
    } finally {
      setUploading(false);
    }
  };

  // Open: detect current module
  useEffect(() => {
    if (open && step === 1) {
      setMod(moduleProp ?? detectModule());
    }
  }, [open, step, moduleProp]);

  // Lock scroll when open
  useEffect(() => {
    if (!open) return;
    const prev = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    return () => { document.body.style.overflow = prev; };
  }, [open]);

  const reset = () => {
    setStep(1);
    setType(null);
    setContent('');
    setContact('');
    setShots([]);
    setError(null);
  };

  const close = () => {
    setOpen(false);
    setTimeout(reset, 300); // 等动画完
  };

  const submit = async () => {
    if (!type || !content.trim()) return;
    setSubmitting(true);
    setError(null);
    try {
      await fetchJson('/api/feedback/submit', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          type,
          module: mod || null,
          content: content.trim(),
          contact: contact.trim() || null,
          screenshots: shots.map(s => s.url),
          userAgent: navigator.userAgent.slice(0, 500),
        }),
      });
      setStep(4);
    } catch (e) {
      setError(e instanceof Error ? e.message : String(e));
    } finally {
      setSubmitting(false);
    }
  };

  const next = () => {
    if (step === 1 && !type) return;
    if (step === 2 && !content.trim()) {
      taRef.current?.focus();
      return;
    }
    if (step === 3) {
      submit();
      return;
    }
    setStep((step + 1) as typeof step);
  };

  const back = () => setStep((Math.max(1, step - 1)) as typeof step);

  const canNext = step === 1 ? !!type : step === 2 ? content.trim().length > 0 : true;
  const progress = ((step === 4 ? 4 : step) / 4) * 100;

  return (
    <>
      {/* Floating Action Button */}
      <div className="fixed bottom-20 right-4 md:bottom-6 md:right-6 z-[60]">
        <motion.button
          initial={{ scale: 0, opacity: 0 }}
          animate={{ scale: 1, opacity: 1 }}
          transition={{ delay: 0.4, type: 'spring', stiffness: 300, damping: 20 }}
          whileHover={{ scale: 1.08 }}
          whileTap={{ scale: 0.92 }}
          onClick={() => setMenuOpen(m => !m)}
          className="w-12 h-12 rounded-full bg-gradient-to-br from-blue-500 to-cyan-400 text-white shadow-lg shadow-blue-200 flex items-center justify-center group"
          aria-label="反馈"
          title="提建议 / 我的反馈"
        >
          <MessageCircleHeart size={20} className="drop-shadow group-hover:scale-110 transition-transform" />
          <span className="absolute -top-0.5 -right-0.5 w-3 h-3 rounded-full bg-amber-300 ring-2 ring-white animate-pulse" />
        </motion.button>

        <AnimatePresence>
          {menuOpen && (
            <motion.div
              initial={{ opacity: 0, scale: 0.9, y: 8 }}
              animate={{ opacity: 1, scale: 1, y: 0 }}
              exit={{ opacity: 0, scale: 0.9, y: 8 }}
              transition={{ duration: 0.15 }}
              className="absolute bottom-14 right-0 bg-white rounded-2xl shadow-xl border border-slate-100 p-1.5 min-w-[148px] flex flex-col gap-0.5"
            >
              <button
                onClick={() => { setMenuOpen(false); setOpen(true); }}
                className="flex items-center gap-2 px-3 py-2 text-[12px] font-bold text-slate-700 rounded-lg hover:bg-blue-50 hover:text-blue-600 text-left"
              >
                <Sparkles size={14} className="text-blue-500" /> 提个建议
              </button>
              <button
                onClick={() => { setMenuOpen(false); setHistoryOpen(true); }}
                className="flex items-center gap-2 px-3 py-2 text-[12px] font-bold text-slate-700 rounded-lg hover:bg-emerald-50 hover:text-emerald-600 text-left"
              >
                <Inbox size={14} className="text-emerald-500" /> 我的反馈
              </button>
            </motion.div>
          )}
        </AnimatePresence>

        {/* 点击外面关菜单 */}
        {menuOpen && (
          <div
            className="fixed inset-0 z-[-1]"
            onClick={() => setMenuOpen(false)}
          />
        )}
      </div>

      <FeedbackHistoryDrawer open={historyOpen} onClose={() => setHistoryOpen(false)} />

      {/* Modal */}
      <AnimatePresence>
        {open && (
          <motion.div
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            exit={{ opacity: 0 }}
            className="fixed inset-0 z-[90] bg-slate-900/40 backdrop-blur-sm flex items-end md:items-center justify-center"
            // 不允许点击背景关闭：避免用户输入到一半误触遮罩丢失内容
          >
            <motion.div
              initial={{ y: '100%', opacity: 0 }}
              animate={{ y: 0, opacity: 1 }}
              exit={{ y: '100%', opacity: 0 }}
              transition={{ y: { type: 'spring', damping: 28, stiffness: 320 }, opacity: { duration: 0.18 } }}
              className="bg-white w-full md:max-w-md md:rounded-3xl rounded-t-3xl shadow-2xl max-h-[92vh] overflow-hidden flex flex-col"
              onClick={(e) => e.stopPropagation()}
            >
              {/* Drag handle */}
              <div className="flex justify-center pt-2.5 pb-1">
                <div className="w-10 h-1 rounded-full bg-slate-300" />
              </div>

              {/* Header + progress */}
              <div className="px-4 pb-3 border-b border-slate-100">
                <div className="flex items-center justify-between mb-2">
                  <div className="flex items-center gap-2">
                    <div className="w-7 h-7 rounded-lg bg-gradient-to-br from-blue-500 to-cyan-400 flex items-center justify-center">
                      <Sparkles size={14} className="text-white" />
                    </div>
                    <div>
                      <div className="text-sm font-black text-slate-800 leading-tight">
                        {step === 4 ? '收到啦~' : '提个建议'}
                      </div>
                      <div className="text-[10px] text-slate-400 font-bold">
                        {step === 1 && '第一步 / 共 3 步'}
                        {step === 2 && '第二步 / 共 3 步'}
                        {step === 3 && '第三步 / 共 3 步'}
                        {step === 4 && '感谢你的反馈'}
                      </div>
                    </div>
                  </div>
                  <button onClick={close} className="p-1.5 -mr-1 text-slate-400 hover:text-slate-700">
                    <X size={18} />
                  </button>
                </div>
                <div className="h-1 bg-slate-100 rounded-full overflow-hidden">
                  <motion.div
                    initial={false}
                    animate={{ width: `${progress}%` }}
                    transition={{ type: 'spring', damping: 28, stiffness: 280 }}
                    className="h-full bg-gradient-to-r from-blue-500 to-cyan-400 rounded-full"
                  />
                </div>
              </div>

              {/* Body */}
              <div className="flex-1 overflow-y-auto px-4 py-4">
                <AnimatePresence mode="wait">
                  {step === 1 && (
                    <motion.div key="s1" initial={{ opacity: 0, x: 12 }} animate={{ opacity: 1, x: 0 }} exit={{ opacity: 0, x: -12 }} transition={{ duration: 0.2 }}>
                      <p className="text-[12px] font-bold text-slate-600 mb-3">想反馈什么呢？</p>
                      <div className="grid grid-cols-1 gap-2">
                        {TYPE_OPTIONS.map(opt => (
                          <button
                            key={opt.key}
                            onClick={() => { setType(opt.key); setStep(2); }}
                            className={`text-left p-3 rounded-2xl border bg-gradient-to-br ${opt.color} hover:shadow-md transition-all flex items-center gap-3 ${type === opt.key ? 'ring-2 ring-blue-400 shadow' : ''}`}
                          >
                            <span className="text-2xl">{opt.emoji}</span>
                            <div className="flex-1 min-w-0">
                              <div className="text-[12px] font-black text-slate-800">{opt.label}</div>
                              <div className="text-[10px] text-slate-500 font-bold mt-0.5">{opt.sub}</div>
                            </div>
                            <ChevronRight size={14} className="text-slate-400 flex-shrink-0" />
                          </button>
                        ))}
                      </div>
                    </motion.div>
                  )}

                  {step === 2 && (
                    <motion.div key="s2" initial={{ opacity: 0, x: 12 }} animate={{ opacity: 1, x: 0 }} exit={{ opacity: 0, x: -12 }} transition={{ duration: 0.2 }} className="space-y-3">
                      <div>
                        <p className="text-[12px] font-bold text-slate-600 mb-2">说说具体内容</p>
                        <textarea
                          ref={taRef}
                          value={content}
                          onChange={(e) => setContent(e.target.value)}
                          onPaste={(e) => {
                            const items = e.clipboardData?.items;
                            if (!items) return;
                            const imgs: File[] = [];
                            for (let i = 0; i < items.length; i++) {
                              const it = items[i];
                              if (it.kind === 'file' && it.type.startsWith('image/')) {
                                const f = it.getAsFile();
                                if (f) imgs.push(f);
                              }
                            }
                            if (imgs.length > 0) {
                              e.preventDefault();
                              addFiles(imgs);
                            }
                          }}
                          autoFocus
                          rows={5}
                          maxLength={1000}
                          placeholder={
                            type === 'dimension' ? '比如：希望按客户/区域/日期范围 等等切片看里程数据…'
                            : type === 'bug'    ? '比如：氢能页面 04-28 嘉燃经开站显示 153.81，但…（可粘贴截图）'
                            : type === 'ux'     ? '比如：能不能把外部 tab 默认收起，加载快一点…'
                                                : '随便聊聊你的想法'
                          }
                          className="w-full bg-slate-50 border-none rounded-xl p-3 text-[12px] text-slate-700 outline-none focus:ring-2 focus:ring-blue-500/20 resize-none"
                        />
                        <div className="text-right text-[10px] text-slate-300 font-bold mt-1">{content.length} / 1000</div>
                      </div>

                      {/* 截图上传 */}
                      <div>
                        <div className="flex items-center justify-between mb-1.5">
                          <p className="text-[10px] font-bold text-slate-400 uppercase">截图（可选）</p>
                          <span className="text-[10px] text-slate-300 font-bold">{shots.length}/{MAX_SCREENSHOTS}，可粘贴</span>
                        </div>
                        <input
                          ref={fileRef}
                          type="file"
                          accept="image/*"
                          multiple
                          className="hidden"
                          onChange={(e) => { if (e.target.files) addFiles(e.target.files); e.target.value = ''; }}
                        />
                        <div className="flex flex-wrap gap-1.5">
                          {shots.map((s, i) => (
                            <div key={i} className="relative w-16 h-16 rounded-lg overflow-hidden border border-slate-200 bg-slate-50">
                              <img src={s.thumbDataUrl} alt="" className="w-full h-full object-cover" />
                              <button
                                onClick={() => setShots(prev => prev.filter((_, idx) => idx !== i))}
                                className="absolute top-0.5 right-0.5 w-4 h-4 rounded-full bg-slate-900/70 text-white flex items-center justify-center hover:bg-slate-900"
                              >
                                <X size={10} />
                              </button>
                            </div>
                          ))}
                          {shots.length < MAX_SCREENSHOTS && (
                            <button
                              onClick={() => fileRef.current?.click()}
                              disabled={uploading}
                              className="w-16 h-16 rounded-lg border border-dashed border-slate-300 bg-slate-50 hover:bg-slate-100 flex flex-col items-center justify-center gap-0.5 text-slate-400"
                            >
                              {uploading ? <Loader2 size={16} className="animate-spin" /> : <ImagePlus size={16} />}
                              <span className="text-[9px] font-bold">{uploading ? '上传中' : '加截图'}</span>
                            </button>
                          )}
                        </div>
                      </div>

                      <div>
                        <p className="text-[10px] font-bold text-slate-400 uppercase mb-1.5">所在板块</p>
                        <div className="flex gap-1 flex-wrap">
                          {Object.entries(MODULE_LABELS).map(([k, label]) => (
                            <button
                              key={k}
                              onClick={() => setMod(k)}
                              className={`px-2.5 py-1 rounded-full text-[10px] font-bold border transition-all ${mod === k ? 'bg-blue-50 border-blue-200 text-blue-600' : 'bg-white border-slate-200 text-slate-500 hover:border-slate-300'}`}
                            >
                              {label}
                            </button>
                          ))}
                        </div>
                      </div>

                      {error && <div className="text-[11px] text-rose-500 font-bold">{error}</div>}
                    </motion.div>
                  )}

                  {step === 3 && (
                    <motion.div key="s3" initial={{ opacity: 0, x: 12 }} animate={{ opacity: 1, x: 0 }} exit={{ opacity: 0, x: -12 }} transition={{ duration: 0.2 }} className="space-y-3">
                      <p className="text-[12px] font-bold text-slate-600">方便留个联系方式吗？</p>
                      <p className="text-[11px] text-slate-400 font-bold">非必填。留下我们可以跟进进展，没留也不影响提交～</p>
                      <input
                        type="text"
                        value={contact}
                        onChange={(e) => setContact(e.target.value)}
                        autoFocus
                        maxLength={120}
                        placeholder="微信 / 钉钉 / 邮箱 / 手机号 都行"
                        className="w-full bg-slate-50 border-none rounded-xl p-3 text-[12px] text-slate-700 outline-none focus:ring-2 focus:ring-blue-500/20"
                      />
                      <div className="bg-slate-50 rounded-xl p-3 mt-1">
                        <div className="text-[10px] font-bold text-slate-400 uppercase mb-1.5">提交概览</div>
                        <div className="text-[11px] text-slate-600 space-y-1">
                          <div>类型：<span className="font-bold text-slate-800">{TYPE_OPTIONS.find(t => t.key === type)?.label}</span></div>
                          <div>板块：<span className="font-bold text-slate-800">{MODULE_LABELS[mod] || '通用'}</span></div>
                          <div className="break-words">内容：<span className="font-bold text-slate-800 line-clamp-3">{content}</span></div>
                        </div>
                      </div>
                      {error && <div className="text-[11px] text-rose-500 font-bold">{error}</div>}
                    </motion.div>
                  )}

                  {step === 4 && (
                    <motion.div key="s4" initial={{ opacity: 0, scale: 0.9 }} animate={{ opacity: 1, scale: 1 }} transition={{ duration: 0.3 }} className="text-center py-6">
                      <motion.div
                        initial={{ scale: 0, rotate: -180 }}
                        animate={{ scale: 1, rotate: 0 }}
                        transition={{ type: 'spring', damping: 12, stiffness: 200, delay: 0.1 }}
                        className="w-16 h-16 rounded-full bg-gradient-to-br from-emerald-400 to-cyan-400 mx-auto flex items-center justify-center mb-3"
                      >
                        <Check size={28} strokeWidth={3} className="text-white" />
                      </motion.div>
                      <div className="text-base font-black text-slate-800 mb-1">谢谢你的反馈 ❤️</div>
                      <div className="text-[12px] text-slate-500 font-bold leading-relaxed">产品同学会认真看每一条<br />有进展会通过你留的联系方式同步</div>
                    </motion.div>
                  )}
                </AnimatePresence>
              </div>

              {/* Footer */}
              {step < 4 && (
                <div className="px-4 py-3 border-t border-slate-100 flex items-center gap-2">
                  {step > 1 && (
                    <button
                      onClick={back}
                      className="px-3 py-2 rounded-xl text-[12px] font-bold text-slate-500 hover:bg-slate-50 flex items-center gap-1"
                    >
                      <ChevronLeft size={14} /> 上一步
                    </button>
                  )}
                  <div className="flex-1" />
                  <button
                    onClick={next}
                    disabled={!canNext || submitting}
                    className="px-4 py-2 rounded-xl text-[12px] font-bold bg-blue-600 text-white shadow shadow-blue-100 disabled:bg-slate-200 disabled:text-slate-400 disabled:shadow-none flex items-center gap-1"
                  >
                    {submitting ? '提交中…' : step === 3 ? '提交' : '下一步'}
                    {!submitting && step !== 3 && <ChevronRight size={14} />}
                  </button>
                </div>
              )}
              {step === 4 && (
                <div className="px-4 py-3 border-t border-slate-100">
                  <button
                    onClick={close}
                    className="w-full py-2.5 rounded-xl text-[12px] font-bold bg-blue-600 text-white shadow shadow-blue-100"
                  >
                    完成
                  </button>
                </div>
              )}
            </motion.div>
          </motion.div>
        )}
      </AnimatePresence>
    </>
  );
}
