import type { InjectionKey } from 'vue';

import type { FileAccess, FileAction } from './fileAccess';

import { computed, inject } from 'vue';

export interface FilePermissionView {
  enabled: boolean;
  taskId: string;
  formId: string;
  status: 'error' | 'loading' | 'ready';
  revision?: string;
  fields?: Record<string, FileAccess>;
}

export const filePermissionFormKey: InjectionKey<() => { modelId: string; readOnly?: boolean; view?: FilePermissionView }> = Symbol('file-permission-form');
export const workflowFileSubmitPendingKey: InjectionKey<() => boolean> = Symbol('workflow-file-submit-pending');

function applyReadOnlyLimit(access: FileAccess | undefined, readOnly: boolean): FileAccess | undefined {
  if (!readOnly || access === undefined || access.status !== 'ready') return access;
  return {
    ...access,
    actions: {
      ADD: false,
      DOWNLOAD: access.actions?.DOWNLOAD === true,
      EDIT: false,
      REVIEW: false,
      REMOVE: false,
      REPLACE: false,
      VIEW: access.actions?.VIEW === true,
    },
  };
}

/** 服务端明确返回旧实例才沿用旧行为；受控实例缺字段或跨表单响应都关闭动作。 */
export function fieldFileAccess(view: FilePermissionView | undefined, modelId: string, field: string, parent?: string): FileAccess | undefined {
  if (view === undefined || view === null) return undefined;
  if (!modelId || view.formId !== modelId || !view.taskId) return { status: 'error' };
  if (view.enabled === false && view.status === 'ready') return undefined;
  if (view.enabled !== true || view.status !== 'ready' || !view.revision) return { status: view.status === 'loading' ? 'loading' : 'error' };
  return view.fields?.[parent ? `${parent}-${field}` : field] ?? { status: 'error' };
}

export function useFilePermissionAccess(props: { editField: string; editParentField?: string; fileAccess?: FileAccess }) {
  const form = inject(filePermissionFormKey, undefined);
  return computed(() => {
    const context = form?.();
    const inherited = context ? fieldFileAccess(context.view, context.modelId, props.editField, props.editParentField) : undefined;
    // 表单运行态始终是上限，不能被控件上的旧配置覆盖。
    let resolved = inherited;
    if (inherited === undefined) resolved = props.fileAccess;
    else if (props.fileAccess !== undefined && inherited.status === 'ready') {
      resolved =
        props.fileAccess.status === 'ready'
          ? ({
              ...inherited,
              actions: Object.fromEntries(
                Object.entries(inherited.actions ?? {}).map(([key, value]) => [key, value === true && props.fileAccess?.actions?.[key as FileAction] === true]),
              ),
            } as FileAccess)
          : props.fileAccess;
    }
    return applyReadOnlyLimit(resolved, context?.readOnly === true);
  });
}
