import React, { createContext, useContext, useMemo } from 'react';
import type { Company, PlanFactory, YarnRatio } from '../types';

interface PlanDataContextValue {
  operatorNames: Record<string, string>;
  planFactories: PlanFactory[];
  yarnRatios: Record<string, YarnRatio[]>;
  factories: Company[];
  getFactoryName: (factoryId: string) => string;
  getOperatorName: (operatorId: string) => string;
  getYarnRatiosForPlan: (planId: string) => YarnRatio[];
}

const PlanDataContext = createContext<PlanDataContextValue | null>(null);

interface PlanDataProviderProps {
  children: React.ReactNode;
  operatorNames: Record<string, string>;
  planFactories: PlanFactory[];
  yarnRatios: Record<string, YarnRatio[]>;
  factories: Company[];
}

/**
 * 计划数据上下文 Provider
 * 消除 PlanOverview → PlanGroup → PlanCard 的 Prop Drilling
 */
export function PlanDataProvider({
  children,
  operatorNames,
  planFactories,
  yarnRatios,
  factories
}: PlanDataProviderProps) {
  // 使用 useMemo 缓存计算函数，避免不必要的重渲染
  const value = useMemo<PlanDataContextValue>(() => ({
    operatorNames,
    planFactories,
    yarnRatios,
    factories,

    getFactoryName: (factoryId: string) => {
      const factory = factories.find(f => f.id === factoryId);
      return factory?.name || '未知工厂';
    },

    getOperatorName: (operatorId: string) => {
      return operatorNames[operatorId] || '未知操作人';
    },

    getYarnRatiosForPlan: (planId: string) => {
      return yarnRatios[planId] || [];
    }
  }), [operatorNames, planFactories, yarnRatios, factories]);

  return (
    <PlanDataContext.Provider value={value}>
      {children}
    </PlanDataContext.Provider>
  );
}

/**
 * 使用计划数据上下文的 Hook
 * @throws 如果在 PlanDataProvider 外部使用会抛出错误
 */
export function usePlanData(): PlanDataContextValue {
  const context = useContext(PlanDataContext);
  if (!context) {
    throw new Error('usePlanData must be used within a PlanDataProvider');
  }
  return context;
}

/**
 * 可选的计划数据上下文 Hook
 * 在 Provider 外部使用时返回 null 而不是抛出错误
 */
export function usePlanDataOptional(): PlanDataContextValue | null {
  return useContext(PlanDataContext);
}
