import React, { useState, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import { useAuth } from '../../contexts/AuthContext';
import { supabase } from '../../supabase/client';
import { motion, AnimatePresence } from 'framer-motion';
import { ChevronDown, ChevronRight, ArrowLeft, Link2, Clipboard, Check, Loader2, X } from 'lucide-react';
import { ProcessFlow } from '../../components/ProcessFlow';
import { notifyStepCompleted, notifyPlanUpdated } from '../../utils/notifications';
import { getSupabaseUrl } from '../../supabase/client';
import type { ProductionPlan, PlanProcessStep, Company, Profile } from '../../types';

const statusMap: Record<string, { label: string; color: string }> = {
  pending: { label: '待确定', color: 'bg-yellow-100 text-yellow-700' },
  producing: { label: '生产中', color: 'bg-blue-100 text-blue-700' },
  completed: { label: '已完成', color: 'bg-green-100 text-green-700' }
};

interface PlanGroup {
  purchaserId: string;
  purchaserName: string;
  plans: (ProductionPlan & { processSteps: PlanProcessStep[]; inventoryRecords: { time: string; quantity: number; rolls: number | null }[] })[];
}

export function TextilePlanOverview() {
  const navigate = useNavigate();
  const { auth } = useAuth();
  const [groups, setGroups] = useState<PlanGroup[]>([]);
  const [expandedGroups, setExpandedGroups] = useState<Set<string>>(new Set());
  const [expandedPlan, setExpandedPlan] = useState<string | null>(null);
  const [loading, setLoading] = useState(true);
  const [confirming, setConfirming] = useState<string | null>(null);
  const [rejecting, setRejecting] = useState<string | null>(null);
  const [showRejectModal, setShowRejectModal] = useState(false);
  const [rejectStepId, setRejectStepId] = useState<string | null>(null);
  const [rejectReason, setRejectReason] = useState('');
  const [importLink, setImportLink] = useState('');
  const [operatorNames, setOperatorNames] = useState<Record<string, string>>({});

  useEffect(() => {
    if (!auth.company) return;
    fetchPlans();

    // 订阅入库记录变化，实现实时更新
    const subscription = supabase
      .channel('plan_overview_inventory_changes')
      .on(
        'postgres_changes',
        {
          event: '*',
          schema: 'public',
          table: 'inventory_records'
        },
        () => {
          // 有入库记录变化时刷新数据
          fetchPlans();
        }
      )
      .subscribe();

    return () => {
      subscription.unsubscribe();
    };
  }, [auth.company]);

  const fetchPlans = async () => {
    // 获取关联到当前纺织厂的计划
    const { data: planFactories } = await supabase
      .from('plan_factories')
      .select('plan_id')
      .eq('factory_id', auth.company!.id)
      .eq('factory_type', 'textile');

    if (!planFactories || planFactories.length === 0) {
      setGroups([]);
      setLoading(false);
      return;
    }

    const planIds = planFactories.map(pf => pf.plan_id);

    // 获取计划详情
    const { data: planData } = await supabase
      .from('production_plans')
      .select('*')
      .in('id', planIds)
      .order('created_at', { ascending: false });

    if (!planData || planData.length === 0) {
      setGroups([]);
      setLoading(false);
      return;
    }

    // 获取所有流程步骤
    const { data: stepsData } = await supabase
      .from('plan_process_steps')
      .select('*')
      .in('plan_id', planIds);

    // 获取操作人信息
    const operatorIds = [...new Set((stepsData || []).filter(s => s.operator_id).map(s => s.operator_id).filter(Boolean))] as string[];
    if (operatorIds.length > 0) {
      const { data: profilesData } = await supabase
        .from('profiles')
        .select('id, username')
        .in('id', operatorIds);
      
      const names: Record<string, string> = {};
      (profilesData || []).forEach(p => {
        names[p.id] = p.username;
      });
      setOperatorNames(names);
    }

    // 获取采购商公司信息
    const purchaserIds = [...new Set(planData.map(p => p.purchaser_id))];
    const { data: companiesData } = await supabase
      .from('companies')
      .select('*')
      .in('id', purchaserIds);

    const companyMap: Record<string, string> = {};
    (companiesData || []).forEach(c => { companyMap[c.id] = c.name; });

    // 获取所有计划的入库记录
    const { data: inventoryData } = await supabase
      .from('inventory_records')
      .select('plan_id, quantity, rolls, created_at')
      .in('plan_id', planIds)
      .order('created_at', { ascending: false });

    // 按采购商分组
    const grouped: Record<string, PlanGroup> = {};
    planData.forEach(plan => {
      const pid = plan.purchaser_id;
      if (!grouped[pid]) {
        grouped[pid] = {
          purchaserId: pid,
          purchaserName: companyMap[pid] || '未知布行',
          plans: []
        };
      }
      const processSteps = (stepsData || [])
        .filter(s => s.plan_id === plan.id)
        .sort((a, b) => {
          const order = ['confirm', 'yarn_purchase', 'dyeing', 'machine_start', 'fabric_warehouse'];
          return order.indexOf(a.step_type) - order.indexOf(b.step_type);
        });
      const inventoryRecords = (inventoryData || [])
        .filter(r => r.plan_id === plan.id)
        .map(r => ({ time: r.created_at, quantity: r.quantity, rolls: r.rolls }));
      grouped[pid].plans.push({ ...plan, processSteps, inventoryRecords });
    });

    const groupList = Object.values(grouped);
    setGroups(groupList);
    // 默认展开第一个组
    if (groupList.length > 0) {
      setExpandedGroups(new Set([groupList[0].purchaserId]));
    }
    setLoading(false);
  };

  const toggleGroup = (id: string) => {
    setExpandedGroups(prev => {
      const next = new Set(prev);
      if (next.has(id)) next.delete(id);
      else next.add(id);
      return next;
    });
  };

  // 从 hash 路由链接中提取查询参数
  const extractParamsFromLink = (link: string) => {
    const hashMatch = link.match(/#\/import\?(.+)$/);
    if (hashMatch) {
      const queryString = hashMatch[1];
      const params = new URLSearchParams(queryString);
      return {
        token: params.get('token'),
        plan: params.get('plan'),
        type: params.get('type')
      };
    }
    try {
      const url = new URL(link, window.location.origin);
      return {
        token: url.searchParams.get('token'),
        plan: url.searchParams.get('plan'),
        type: url.searchParams.get('type')
      };
    } catch {
      return { token: null, plan: null, type: null };
    }
  };

  const handleImportFromLink = () => {
    if (!importLink.trim()) return;

    const { token, plan, type } = extractParamsFromLink(importLink);

    if (token) {
      navigate(`/import?token=${token}`);
    } else if (plan && type) {
      navigate(`/import?plan=${plan}&type=${type}`);
    } else {
      alert('无效的链接格式，请确保链接包含 token 或 plan 参数');
    }
  };

  const handlePasteFromClipboard = async () => {
    try {
      const text = await navigator.clipboard.readText();
      if (text.includes('/import?') || text.includes('#/import?')) {
        setImportLink(text);
        const { token, plan, type } = extractParamsFromLink(text);

        if (token) {
          navigate(`/import?token=${token}`);
        } else if (plan && type) {
          navigate(`/import?plan=${plan}&type=${type}`);
        } else {
          alert('链接格式不正确，请检查链接是否完整');
        }
      } else {
        alert('剪贴板中没有检测到有效的导入链接');
      }
    } catch (err) {
      console.error('读取剪贴板失败:', err);
      alert('无法读取剪贴板，请手动粘贴链接');
    }
  };

  // 打开拒绝弹窗
  const handleOpenRejectModal = (stepId: string) => {
    setRejectStepId(stepId);
    setRejectReason('');
    setShowRejectModal(true);
  };

  // 关闭拒绝弹窗
  const handleCloseRejectModal = () => {
    setShowRejectModal(false);
    setRejectStepId(null);
    setRejectReason('');
  };

  // 处理拒绝计划
  const handleRejectStep = async () => {
    if (!rejectStepId || !rejectReason.trim()) {
      alert('请输入拒绝原因');
      return;
    }

    setRejecting(rejectStepId);
    const now = new Date().toISOString();

    try {
      // 获取步骤信息
      const { data: step } = await supabase
        .from('plan_process_steps')
        .select('plan_id')
        .eq('id', rejectStepId)
        .maybeSingle();

      if (!step?.plan_id) {
        setRejecting(null);
        handleCloseRejectModal();
        return;
      }

      // 更新步骤状态为拒绝（使用 notes 字段记录拒绝原因）
      const { error } = await supabase
        .from('plan_process_steps')
        .update({
          status: 'pending' as const,
          notes: `拒绝原因: ${rejectReason.trim()}`,
          timestamp: now,
          operator_id: auth.user?.id
        })
        .eq('id', rejectStepId);

      if (error) {
        console.error('拒绝失败:', error);
        alert('拒绝失败，请重试');
        setRejecting(null);
        return;
      }

      // 发送拒绝通知给采购商
      await notifyPlanUpdated(step.plan_id, 'rejected', auth.company!.id, auth.user!.id);

      // 刷新数据
      await fetchPlans();
      handleCloseRejectModal();
    } catch (err) {
      console.error('拒绝失败:', err);
      alert('拒绝失败，请重试');
    }
    setRejecting(null);
  };

  const handleConfirmStep = async (stepId: string, quantity?: number, rolls?: number) => {
    setConfirming(stepId);
    const now = new Date().toISOString();

    // 获取步骤信息
    const { data: step } = await supabase
      .from('plan_process_steps')
      .select('step_type, plan_id')
      .eq('id', stepId)
      .maybeSingle();

    const planId = step?.plan_id;

    if (!planId) {
      setConfirming(null);
      return;
    }

    // 如果是坯布入库，使用 Edge Function 进行事务处理
    if (step?.step_type === 'fabric_warehouse' && quantity && quantity > 0) {
      // 获取纺织厂的仓库和工厂信息
      const { data: warehouse } = await supabase
        .from('warehouses')
        .select('id')
        .eq('company_id', auth.company!.id)
        .eq('type', 'fabric')
        .maybeSingle();

      // 获取工厂信息（地址或名称）
      const { data: factoryInfo } = await supabase
        .from('companies')
        .select('name, address')
        .eq('id', auth.company!.id)
        .maybeSingle();

      // 仓库位置：优先使用地址，没有则使用工厂名称
      const warehouseLocation = factoryInfo?.address || factoryInfo?.name || '';

      // 获取计划信息（包括采购商ID和采购价）
      const { data: plan } = await supabase
        .from('production_plans')
        .select('completed_quantity, target_quantity, purchaser_id, production_price')
        .eq('id', planId)
        .maybeSingle();

      if (plan) {
        const newCompletedQuantity = plan.completed_quantity + quantity;
        const progressPercent = (newCompletedQuantity / plan.target_quantity) * 100;
        const pricePerMeter = plan.production_price || 0;
        const amount = quantity * pricePerMeter;

        // 使用 Edge Function 进行入库事务处理
        const session = (await supabase.auth.getSession()).data.session;
        const headers: Record<string, string> = { 'Content-Type': 'application/json' };
        if (session) {
          headers['Authorization'] = `Bearer ${session.access_token}`;
        }

        const response = await fetch(`${getSupabaseUrl()}/functions/v1/fabric-warehouse-inbound`, {
          method: 'POST',
          headers,
          body: JSON.stringify({
            planId: planId,
            quantity: quantity,
            rolls: rolls || 0,
            warehouseId: warehouse?.id || null,
            warehouseLocation: warehouseLocation,
            operatorId: auth.user?.id,
            pricePerMeter: pricePerMeter,
          }),
        });

        const result = await response.json();
        if (!response.ok) {
          throw new Error(result.error || '入库操作失败');
        }

        const inventoryRecord = result.data?.inventoryRecord;

        // 创建或更新应付账款记录
        if (inventoryRecord) {
          // 检查是否已存在应付账款记录
          const { data: existingAP } = await supabase
            .from('accounts_payable')
            .select('*')
            .eq('plan_id', planId)
            .eq('textile_factory_id', auth.company!.id)
            .maybeSingle();

          if (existingAP) {
            // 更新应付账款
            await supabase
              .from('accounts_payable')
              .update({
                total_quantity: existingAP.total_quantity + quantity,
                total_amount: existingAP.total_amount + amount,
                unpaid_quantity: existingAP.unpaid_quantity + quantity,
                unpaid_amount: existingAP.unpaid_amount + amount,
                updated_at: now
              })
              .eq('id', existingAP.id);

            // 创建应付账款明细
            await supabase
              .from('accounts_payable_items')
              .insert({
                accounts_payable_id: existingAP.id,
                inventory_record_id: inventoryRecord.id,
                quantity: quantity,
                rolls: rolls || 0,
                price_per_meter: pricePerMeter,
                amount: amount,
                status: 'unpaid',
                created_at: now
              });
          } else {
            // 创建新的应付账款
            const { data: newAP } = await supabase
              .from('accounts_payable')
              .insert({
                plan_id: planId,
                purchaser_id: plan.purchaser_id,
                textile_factory_id: auth.company!.id,
                total_quantity: quantity,
                total_amount: amount,
                unpaid_quantity: quantity,
                unpaid_amount: amount,
                price_per_meter: pricePerMeter,
                status: 'unpaid',
                created_at: now,
                updated_at: now
              })
              .select()
              .single();

            if (newAP) {
              // 创建应付账款明细
              await supabase
                .from('accounts_payable_items')
                .insert({
                  accounts_payable_id: newAP.id,
                  inventory_record_id: inventoryRecord.id,
                  quantity: quantity,
                  rolls: rolls || 0,
                  price_per_meter: pricePerMeter,
                  amount: amount,
                  status: 'unpaid',
                  created_at: now
                });
            }
          }
        }

        // 如果进度达到97%或以上，标记步骤为完成，否则标记为进行中
        if (progressPercent >= 97) {
          await supabase
            .from('plan_process_steps')
            .update({
              status: 'completed' as const,
              timestamp: now,
              operator_id: auth.user?.id
            })
            .eq('id', stepId);
        } else {
          // 进度未达到97%，标记步骤为进行中（active）
          await supabase
            .from('plan_process_steps')
            .update({
              status: 'active' as const,
              timestamp: now,
              operator_id: auth.user?.id
            })
            .eq('id', stepId);
        }
      }
    } else {
      // 其他步骤直接更新状态
      const { error } = await supabase
        .from('plan_process_steps')
        .update({
          status: 'completed' as const,
          timestamp: now,
          operator_id: auth.user?.id
        })
        .eq('id', stepId);

      if (error) {
        console.error('确认失败:', error);
        alert('确认失败，请重试');
        setConfirming(null);
        return;
      }
    }

    // 更新计划状态
    if (step?.step_type === 'confirm') {
      await supabase
        .from('production_plans')
        .update({ status: 'producing' as const })
        .eq('id', planId);

      // 发送计划开始生产通知
      await notifyPlanUpdated(planId, 'producing', auth.company!.id, auth.user!.id);
    }

    // 检查是否所有步骤都已完成
    const { data: allSteps } = await supabase
      .from('plan_process_steps')
      .select('status')
      .eq('plan_id', planId);

    const allCompleted = allSteps?.every(s => s.status === 'completed');
    if (allCompleted) {
      await supabase
        .from('production_plans')
        .update({ status: 'completed' as const })
        .eq('id', planId);

      // 发送计划完成通知
      await notifyPlanUpdated(planId, 'completed', auth.company!.id, auth.user!.id);
    }

    // 发送节点完成通知
    const stepNames: Record<string, string> = {
      confirm: '确认计划',
      yarn_purchase: '采纱',
      dyeing: '染纱',
      machine_start: '上机',
      fabric_warehouse: '坯布生产'
    };
    const stepName = stepNames[step?.step_type || ''] || '生产节点';
    await notifyStepCompleted(
      planId,
      stepName,
      auth.company!.id,
      auth.user!.id,
      step?.step_type === 'fabric_warehouse' ? { quantity, rolls } : undefined
    );

    // 刷新数据
    await fetchPlans();
    setConfirming(null);
  };

  // 将步骤转换为 ProcessFlow 需要的格式
  const formatProcessNodes = (steps: PlanProcessStep[]) => {
    return steps.map(step => ({
      id: step.id,
      name: step.step_type,
      status: step.status,
      timestamp: step.timestamp,
      stepType: step.step_type,
      operatorName: step.operator_id ? operatorNames[step.operator_id] : undefined
    }));
  };

  return (
    <div className="min-h-screen bg-gray-50 p-3 sm:p-4 md:p-6">
      <div className="max-w-6xl mx-auto">
        <div className="flex items-center gap-2 sm:gap-3 md:gap-4 mb-4 sm:mb-5 md:mb-6">
          <motion.button
            whileTap={{ scale: 0.95 }}
            onClick={() => navigate('/textile')}
            className="p-2 hover:bg-gray-200 rounded-full transition-colors will-change-transform"
          >
            <ArrowLeft className="w-5 h-5 sm:w-6 sm:h-6 text-gray-600" />
          </motion.button>
          <h1 className="text-lg sm:text-xl md:text-2xl font-bold text-gray-800">计划总览</h1>
        </div>

        {/* 导入链接区域 */}
        <motion.div
          initial={{ opacity: 0, y: 10 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ duration: 0.3 }}
          className="bg-white rounded-xl shadow-sm border border-gray-200 p-3 sm:p-4 mb-4 sm:mb-5 md:mb-6"
        >
          <div className="flex items-center justify-between mb-2 sm:mb-3">
            <h2 className="font-semibold text-gray-800 flex items-center gap-2 text-sm sm:text-base">
              <Link2 className="w-4 h-4 sm:w-5 sm:h-5 text-blue-600" />
              导入关联计划
            </h2>
            <motion.button
              whileTap={{ scale: 0.97 }}
              onClick={handlePasteFromClipboard}
              className="flex items-center gap-1 px-2 sm:px-3 py-1 sm:py-1.5 text-xs sm:text-sm text-blue-600 hover:bg-blue-50 rounded-lg transition-colors will-change-transform"
            >
              <Clipboard className="w-3.5 h-3.5 sm:w-4 sm:h-4" />
              识别剪贴板
            </motion.button>
          </div>
          <div className="flex gap-2">
            <input
              type="text"
              value={importLink}
              onChange={(e) => setImportLink(e.target.value)}
              placeholder="粘贴采购商分享的链接..."
              className="flex-1 px-3 sm:px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 text-xs sm:text-sm"
            />
            <motion.button
              whileTap={{ scale: 0.97 }}
              onClick={handleImportFromLink}
              disabled={!importLink.trim()}
              className="px-3 sm:px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed text-xs sm:text-sm font-medium will-change-transform"
            >
              导入
            </motion.button>
          </div>
        </motion.div>

        {loading ? (
          <div className="flex flex-col items-center justify-center py-12 sm:py-16">
            <motion.div
              animate={{ rotate: 360 }}
              transition={{ duration: 1, repeat: Infinity, ease: 'linear' }}
              className="w-6 h-6 sm:w-8 sm:h-8 border-2 border-blue-500 border-t-transparent rounded-full mb-3"
            />
            <p className="text-gray-400 text-sm">加载中...</p>
          </div>
        ) : groups.length === 0 ? (
          <motion.div
            initial={{ opacity: 0, y: 10 }}
            animate={{ opacity: 1, y: 0 }}
            className="text-center py-12 sm:py-16 text-gray-400"
          >
            <p className="mb-2 text-sm sm:text-base">暂无关联计划</p>
            <p className="text-xs sm:text-sm text-gray-400">请使用上方输入框粘贴采购商分享的链接</p>
          </motion.div>
        ) : (
          <div className="space-y-3 sm:space-y-4">
            {groups.map((group, groupIndex) => (
              <motion.div
                key={group.purchaserId}
                initial={{ opacity: 0, y: 15 }}
                animate={{ opacity: 1, y: 0 }}
                transition={{ delay: groupIndex * 0.08, duration: 0.35 }}
                className="bg-white rounded-xl shadow-sm border border-gray-200 overflow-hidden"
              >
                <motion.div
                  onClick={() => toggleGroup(group.purchaserId)}
                  whileTap={{ scale: 0.995 }}
                  className="flex items-center justify-between p-3 sm:p-4 cursor-pointer hover:bg-gray-50 transition-colors will-change-transform"
                >
                  <div className="flex items-center gap-2 sm:gap-3">
                    <motion.button
                      animate={{ rotate: expandedGroups.has(group.purchaserId) ? 90 : 0 }}
                      transition={{ duration: 0.2 }}
                      className="p-1 rounded hover:bg-gray-200 will-change-transform"
                    >
                      <ChevronRight size={18} className="sm:w-5 sm:h-5" />
                    </motion.button>
                    <div>
                      <h3 className="font-semibold text-gray-800 text-sm sm:text-base">{group.purchaserName}</h3>
                      <span className="text-xs sm:text-sm text-gray-500">计划 ({group.plans.length})</span>
                    </div>
                  </div>
                </motion.div>
                <AnimatePresence>
                  {expandedGroups.has(group.purchaserId) && (
                    <motion.div
                      initial={{ height: 0, opacity: 0 }}
                      animate={{ height: 'auto', opacity: 1 }}
                      exit={{ height: 0, opacity: 0 }}
                      transition={{ duration: 0.3, ease: [0.25, 0.46, 0.45, 0.94] }}
                      className="border-t border-gray-100"
                    >
                      <div className="p-3 sm:p-4 space-y-3 sm:space-y-4">
                        {group.plans.map((plan, planIndex) => {
                          const progress = plan.target_quantity > 0
                            ? Math.round((plan.completed_quantity / plan.target_quantity) * 100)
                            : 0;
                          return (
                            <motion.div
                              key={plan.id}
                              initial={{ opacity: 0, y: 10 }}
                              animate={{ opacity: 1, y: 0 }}
                              transition={{ delay: planIndex * 0.05, duration: 0.3 }}
                              className="border border-gray-200 rounded-lg overflow-hidden"
                            >
                              <motion.div
                                onClick={() => setExpandedPlan(expandedPlan === plan.id ? null : plan.id)}
                                whileTap={{ scale: 0.995 }}
                                className="p-3 sm:p-4 cursor-pointer hover:bg-gray-50 transition-colors will-change-transform"
                              >
                                <div className="flex items-start justify-between gap-2">
                                  <div className="min-w-0 flex-1">
                                    <div className="flex items-center gap-2 mb-1.5 sm:mb-2">
                                      <span className={`px-2 py-0.5 sm:py-1 text-[10px] sm:text-xs rounded-full ${statusMap[plan.status]?.color || 'bg-gray-100'}`}>
                                        {statusMap[plan.status]?.label || plan.status}
                                      </span>
                                    </div>
                                    <p className="text-xs sm:text-sm text-gray-600 truncate">{plan.fabric_code}</p>
                                    <p className="text-[10px] sm:text-xs text-gray-400">{plan.plan_code}</p>
                                  </div>
                                  <div className="text-right text-xs sm:text-sm text-gray-600 flex-shrink-0">
                                    <p>计划: {plan.target_quantity}米</p>
                                    <p>已入库: {plan.completed_quantity}米</p>
                                  </div>
                                </div>
                                <div className="mt-2 sm:mt-3">
                                  <div className="flex justify-between text-[10px] sm:text-xs text-gray-500 mb-1">
                                    <span>进度</span>
                                    <span>{progress}%</span>
                                  </div>
                                  <div className="h-1.5 sm:h-2 bg-gray-200 rounded-full overflow-hidden">
                                    <motion.div
                                      initial={{ width: 0 }}
                                      animate={{ width: `${progress}%` }}
                                      transition={{ duration: 0.6, delay: 0.1, ease: [0.25, 0.46, 0.45, 0.94] }}
                                      className="h-full bg-gradient-to-r from-blue-500 to-cyan-500 rounded-full will-change-transform"
                                    />
                                  </div>
                                </div>
                              </motion.div>
                              <AnimatePresence>
                                {expandedPlan === plan.id && plan.processSteps.length > 0 && (
                                  <motion.div
                                    initial={{ height: 0, opacity: 0 }}
                                    animate={{ height: 'auto', opacity: 1 }}
                                    exit={{ height: 0, opacity: 0 }}
                                    transition={{ duration: 0.25 }}
                                    className="border-t border-gray-100 p-3 sm:p-4 bg-gray-50"
                                  >
                                    <h5 className="font-medium mb-3 sm:mb-4 flex items-center gap-2 text-sm">
                                      <Check className="w-4 h-4 text-blue-600" />
                                      生产记录
                                    </h5>
                                    <ProcessFlow
                                      nodes={formatProcessNodes(plan.processSteps)}
                                      onConfirm={(stepId, quantity, rolls) => handleConfirmStep(stepId, quantity, rolls)}
                                      onReject={handleOpenRejectModal}
                                      confirmLoading={confirming}
                                      showConfirmButton={true}
                                      planTargetQuantity={plan.target_quantity}
                                      planCompletedQuantity={plan.completed_quantity}
                                      isPlanLocked={plan.status === 'completed'}
                                      lastInventoryTime={plan.inventoryRecords[0]?.time}
                                      inventoryRecords={plan.inventoryRecords}
                                    />
                                  </motion.div>
                                )}
                              </AnimatePresence>
                            </motion.div>
                          );
                        })}
                      </div>
                    </motion.div>
                  )}
                </AnimatePresence>
              </motion.div>
            ))}
          </div>
        )}
      </div>

      {/* 拒绝计划弹窗 */}
      <AnimatePresence>
        {showRejectModal && (
          <motion.div
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            exit={{ opacity: 0 }}
            className="fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4"
          >
            <motion.div
              initial={{ scale: 0.95, opacity: 0, y: 20 }}
              animate={{ scale: 1, opacity: 1, y: 0 }}
              exit={{ scale: 0.95, opacity: 0, y: 20 }}
              transition={{ duration: 0.2, ease: [0.25, 0.46, 0.45, 0.94] }}
              className="bg-white rounded-xl p-6 w-full max-w-md shadow-xl"
            >
              <div className="flex items-center gap-3 mb-4">
                <div className="w-10 h-10 rounded-full bg-red-100 flex items-center justify-center">
                  <X className="w-6 h-6 text-red-600" />
                </div>
                <h3 className="text-lg font-semibold text-gray-800">拒绝计划</h3>
              </div>
              <p className="text-sm text-gray-600 mb-4">
                请填写拒绝原因，采购商将收到通知并可以重新调整计划。
              </p>
              <div className="mb-4">
                <label className="block text-sm font-medium text-gray-700 mb-2">
                  拒绝原因 <span className="text-red-500">*</span>
                </label>
                <textarea
                  value={rejectReason}
                  onChange={(e) => setRejectReason(e.target.value)}
                  placeholder="请输入拒绝原因，如：产能不足、价格不合适等..."
                  className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-red-500 focus:border-red-500 text-sm resize-none"
                  rows={4}
                />
              </div>
              <div className="flex gap-3">
                <motion.button
                  whileTap={{ scale: 0.98 }}
                  onClick={handleCloseRejectModal}
                  className="flex-1 py-2 border border-gray-300 rounded-lg text-gray-700 hover:bg-gray-50 text-sm font-medium transition-colors"
                >
                  取消
                </motion.button>
                <motion.button
                  whileTap={{ scale: 0.98 }}
                  onClick={handleRejectStep}
                  disabled={!rejectReason.trim() || rejecting === rejectStepId}
                  className="flex-1 py-2 bg-red-600 text-white rounded-lg hover:bg-red-700 disabled:opacity-50 text-sm font-medium transition-colors flex items-center justify-center gap-2"
                >
                  {rejecting === rejectStepId ? (
                    <Loader2 className="w-4 h-4 animate-spin" />
                  ) : (
                    <X className="w-4 h-4" />
                  )}
                  确认拒绝
                </motion.button>
              </div>
            </motion.div>
          </motion.div>
        )}
      </AnimatePresence>
    </div>
  );
}
