import { readScopedRouteQueryParam } from './share-route-context';

/**
 * 工作流对话分享请求头。
 */
export const WORKFLOW_SHARE_HEADER = 'X-Workflow-Chat-Share-Key';

interface WorkflowShareResolutionOptions<T> {
  currentWorkflowId?: null | T;
  onFailure: (error: unknown) => Promise<void> | void;
  resolve: () => Promise<null | T | undefined>;
  shareKey?: unknown;
}

interface WorkflowShareHeaderOptions {
  pageUrl?: string;
  requestMethod?: string;
  requestUrl?: string;
}

const WORKFLOW_SHARE_ROUTES = ['/share/workflow'];
const WORKFLOW_SHARE_REQUESTS = [
  ['GET', '/api/v1/workflowChat/descriptor'],
  ['GET', '/api/v1/workflowChat/execution'],
  ['GET', '/api/v1/workflowShare/resolve'],
  ['POST', '/api/v1/workflowChat/cancel'],
  ['POST', '/api/v1/workflowChat/resume'],
  ['POST', '/api/v1/workflowChat/run'],
] as const;

/**
 * 从页面地址读取工作流分享密钥，兼容 history 与 hash 路由。
 */
export function readWorkflowShareKey(url?: string): null | string {
  for (const routePath of WORKFLOW_SHARE_ROUTES) {
    const shareKey = readScopedRouteQueryParam(routePath, 'shareKey', url);
    if (shareKey) {
      return shareKey;
    }
  }
  return null;
}

/**
 * 将分享解析失败映射为失效页展示原因。
 */
export function resolveWorkflowShareFailureReason(
  error: unknown,
): 'expired' | 'invalid' {
  const candidate = error as
    | undefined
    | {
        message?: unknown;
        response?: {
          data?: {
            error?: unknown;
            message?: unknown;
          };
        };
      };
  const message = [
    candidate?.response?.data?.message,
    candidate?.response?.data?.error,
    candidate?.message,
  ]
    .map((value) => String(value || '').trim())
    .find(Boolean);
  return message && (message.includes('过期') || /expired/i.test(message))
    ? 'expired'
    : 'invalid';
}

/**
 * 判断当前请求是否属于工作流分享授权白名单。
 */
export function isWorkflowShareRequest(
  requestUrl?: string,
  requestMethod?: string,
) {
  if (!requestUrl || !requestMethod) {
    return false;
  }
  try {
    const parsed = new URL(requestUrl, 'http://easyflow.local');
    const method = requestMethod.trim().toUpperCase();
    return WORKFLOW_SHARE_REQUESTS.some(([allowedMethod, allowedPath]) => {
      return method === allowedMethod && parsed.pathname.endsWith(allowedPath);
    });
  } catch {
    return false;
  }
}

/**
 * 在保留现有请求头的基础上附加工作流分享密钥。
 */
export function withWorkflowShareHeader(
  headers: Record<string, string>,
  options: WorkflowShareHeaderOptions = {},
): Record<string, string> {
  if (!isWorkflowShareRequest(options.requestUrl, options.requestMethod)) {
    return headers;
  }
  const shareKey = readWorkflowShareKey(options.pageUrl);
  if (!shareKey) {
    return headers;
  }
  return {
    ...headers,
    [WORKFLOW_SHARE_HEADER]: shareKey,
  };
}

/**
 * 解析分享地址对应的工作流，并在链接失效时统一收口异常。
 */
export async function resolveWorkflowShareWorkflowId<T>({
  currentWorkflowId,
  onFailure,
  resolve,
  shareKey,
}: WorkflowShareResolutionOptions<T>): Promise<null | T> {
  if (currentWorkflowId !== null && currentWorkflowId !== undefined) {
    return currentWorkflowId;
  }
  const normalizedShareKey = Array.isArray(shareKey)
    ? shareKey.find((value) => String(value || '').trim())
    : shareKey;
  if (!String(normalizedShareKey || '').trim()) {
    return null;
  }
  try {
    return (await resolve()) ?? null;
  } catch (error) {
    await onFailure(error);
    return null;
  }
}
