import React, { createContext, useContext, useMemo } from 'react';
import { useMemoizedFn } from 'ahooks';
import { SalesSdkContext } from "./SalesSdkContext";
import { formatBookingDateTime } from "../utils/bookingDate";

/**
 * SalesSdkBookingContext：把 OS BookingContext 子模块以薄壳形式暴露给 React 消费方。
 *
 * 设计目标：
 *  - **写**（setBookingConfig / setResources / setBookingDate）：透传到 OS BookingContext。
 *  - **读**（getResourcesForProduct / getProductExtend / getResourceErrors）：透传到 OS BookingTicket
 *    的同名方法（OS 那边已经基于 BookingContext.utils 包了一层）。
 *  - 数据加载（`/core/board/management/config`、`/form/schedule`）**不在 SDK 内触发**：
 *    消费方在已经拉到数据的地方一次 `setBookingConfig` / `setResources` 即可。
 *
 * 与 ticketBooking 现有 Info2 / mini-redux **完全解耦**，只服务 saleDetail 等新组件。
 *
 * 该 Provider 为可选：消费方在不需要 booking 上下文的纯 sale 场景里可以不挂载，节省渲染。
 * 挂载时应放在 SalesSdkProvider 内部、Cart/Customer 等其它子 Provider 同级。
 */

export var SalesSdkBookingContext = /*#__PURE__*/createContext(null);
SalesSdkBookingContext.displayName = 'SalesSdkBookingContext';
function ensureMethod(bookingTicket, method) {
  var fn = bookingTicket === null || bookingTicket === void 0 ? void 0 : bookingTicket[method];
  if (typeof fn !== 'function' || !bookingTicket) {
    throw new Error("[SalesSdk] BookingContext: bookingTicket.".concat(String(method), " \u4E0D\u53EF\u7528\uFF0C\u8BF7\u5347\u7EA7 pisellos"));
  }
  return fn.bind(bookingTicket);
}

/**
 * BookingContext Provider —— 极薄壳：所有写都透传到 OS，所有读都调 OS 上的同名方法。
 *
 * 不持有 React state（避免与 OS 数据不一致）；如果消费方需要订阅 booking config 变更，
 * 通过 `useSalesSdk().bookingTicket?.effectsOn('bookingContext:onBookingConfigChange', cb)` 自订阅。
 */
export var SalesSdkBookingContextProvider = function SalesSdkBookingContextProvider(_ref) {
  var _sales$bookingTicket;
  var children = _ref.children;
  var sales = useContext(SalesSdkContext);
  var bookingTicket = (_sales$bookingTicket = sales === null || sales === void 0 ? void 0 : sales.bookingTicket) !== null && _sales$bookingTicket !== void 0 ? _sales$bookingTicket : null;
  var setBookingConfig = useMemoizedFn(function (config) {
    ensureMethod(bookingTicket, 'setBookingConfig')(config);
  });
  var getBookingConfig = useMemoizedFn(function () {
    var _bookingTicket$getBoo;
    return (bookingTicket === null || bookingTicket === void 0 || (_bookingTicket$getBoo = bookingTicket.getBookingConfig) === null || _bookingTicket$getBoo === void 0 ? void 0 : _bookingTicket$getBoo.call(bookingTicket)) || null;
  });
  var setResources = useMemoizedFn(function (resources) {
    ensureMethod(bookingTicket, 'setResources')(resources);
  });
  var getResourcesOrigin = useMemoizedFn(function () {
    var _bookingTicket$getRes;
    return (bookingTicket === null || bookingTicket === void 0 || (_bookingTicket$getRes = bookingTicket.getResourcesOrigin) === null || _bookingTicket$getRes === void 0 ? void 0 : _bookingTicket$getRes.call(bookingTicket)) || [];
  });
  var getResourcesOriginMap = useMemoizedFn(function () {
    var _bookingTicket$getRes2;
    return (bookingTicket === null || bookingTicket === void 0 || (_bookingTicket$getRes2 = bookingTicket.getResourcesOriginMap) === null || _bookingTicket$getRes2 === void 0 ? void 0 : _bookingTicket$getRes2.call(bookingTicket)) || {};
  });

  /**
   * 写入 BookingContext 当前预约时间（统一 `YYYY-MM-DD HH:mm:ss`）。
   *
   * @example
   * setDate(dayjs()); // TimeBar 点「现在」
   * setDate('2026-05-25 14:30:00');
   */
  var setDate = useMemoizedFn(function (date) {
    if (!(bookingTicket !== null && bookingTicket !== void 0 && bookingTicket.setBookingDate)) {
      console.warn('[SalesSdk] setDate: bookingTicket 未就绪，跳过写入');
      return;
    }
    var normalized = formatBookingDateTime(date);
    bookingTicket.setBookingDate(normalized !== null && normalized !== void 0 ? normalized : date);
  });
  var getDate = useMemoizedFn(function () {
    var _bookingTicket$getBoo2;
    return (bookingTicket === null || bookingTicket === void 0 || (_bookingTicket$getBoo2 = bookingTicket.getBookingDate) === null || _bookingTicket$getBoo2 === void 0 ? void 0 : _bookingTicket$getBoo2.call(bookingTicket)) || null;
  });
  var getResourcesForProduct = useMemoizedFn(function (product, options) {
    return ensureMethod(bookingTicket, 'getResourcesForProduct')(product, options);
  });
  var getProductExtend = useMemoizedFn(function (cacheItem, extra) {
    return ensureMethod(bookingTicket, 'getProductExtend')(cacheItem, extra);
  });
  var getResourceErrors = useMemoizedFn(function (resource, cacheItem) {
    return ensureMethod(bookingTicket, 'getResourceErrors')(resource, cacheItem);
  });
  var value = useMemo(function () {
    return {
      setBookingConfig: setBookingConfig,
      getBookingConfig: getBookingConfig,
      setResources: setResources,
      getResourcesOrigin: getResourcesOrigin,
      getResourcesOriginMap: getResourcesOriginMap,
      setDate: setDate,
      getDate: getDate,
      getResourcesForProduct: getResourcesForProduct,
      getProductExtend: getProductExtend,
      getResourceErrors: getResourceErrors
    };
  }, [setBookingConfig, getBookingConfig, setResources, getResourcesOrigin, getResourcesOriginMap, setDate, getDate, getResourcesForProduct, getProductExtend, getResourceErrors]);
  return /*#__PURE__*/React.createElement(SalesSdkBookingContext.Provider, {
    value: value
  }, children);
};
export function useSalesSdkBookingContext() {
  var ctx = useContext(SalesSdkBookingContext);
  if (!ctx) {
    throw new Error('[SalesSdk] useSalesSdkBookingContext 必须在 <SalesSdkBookingContextProvider> 内调用');
  }
  return ctx;
}