import { defineStore } from 'pinia';
import { flow_router, flow_start } from '@/router';

type Record<K extends keyof any, T> = {
  [P in K]?: T;
};

type Values<T> = T[keyof T];

type CrossingKey = '/register' | '/camera' | '/questionnaire';
export type FlowKey = Values<typeof flow_router> | `/crossing${CrossingKey}`;
export type Flow = {
  optional?: boolean;
  done?: { path: '/screen'; countdown: number; title: string };
  crossing?: { title: string; description?: string };
  prev: FlowKey;
  next: FlowKey;
};

export const useFlowStore = defineStore('flow', () => {
  const _router = useRouter();
  const _route = useRoute();
  const _flow = ref<Record<FlowKey, Flow>>({});

  const current = computed(() => {
    let path = _route.path;
    if (!path.startsWith('/crossing')) {
      const source = Object.values(_route.params)
        .filter(Boolean)
        .map((value) => `(?:\\/${value})`)
        .join('');
      path = _route.path.replace(new RegExp(source, 'g'), '');
    }
    return path as FlowKey;
  });
  const flow = computed(() => {
    return _flow.value[current.value] as Flow;
  });

  const $init = (config: string[]) => {
    config = polyfill(config);
    const crossing_ref: Record<CrossingKey, Flow['crossing']> = {
      '/register': {
        title: `建档完成`,
        description: `完成建档的填写`,
      },
      '/camera': {
        title: `拍摄完成`,
        description: `完成舌面象的采集`,
      },
      '/questionnaire': {
        title: `问卷完成`,
        description: `完成问卷的采集`,
      },
    };
    const countdown_ref: Record<FlowKey, number> = {
      '/register': 10,
      '/questionnaire': 10,
      '/pulse': 20,
      '/camera': 20,
      '/alcohol/result': 60,
    };
    const optional_ref: Record<FlowKey, { optional: true }> = {};

    /* 设置 flow 流程节点数据 */
    const set = (prev: FlowKey | void, current: FlowKey, next: string, { optional, ...value }: Partial<Flow> = {}) => {
      _flow.value[current] = Object.assign(value, { prev, next: flow_router[next as keyof typeof flow_router] ?? next }, optional_ref[current]) as Flow;
      if (value.next === '/screen') Reflect.deleteProperty(value, 'next');
      else if (optional) optional_ref[value.next!] = { optional };
      if (value.crossing == null) Reflect.deleteProperty(value, 'crossing');
      return [current, value.next!];
    };

    /* 统一参数配置 */
    if (config.at(-1) !== flow_start) config.push(`${flow_start}?`);
    /* 遍历参数配置 */
    const start = config[0] === flow_start ? config.shift()! : flow_start;
    let current: FlowKey = flow_router[start as keyof typeof flow_router];
    let prev: FlowKey | void = void 0;
    do {
      let next = config.shift();
      if (next?.includes('?')) {
        const [value, title = '获取健康调理方案', countdown = countdown_ref[current] ?? 0] = next?.split('?').map((value) => value || void 0) ?? [];
        // 检查是否添加 [虚拟结果] 节点
        const crossing = crossing_ref[current as CrossingKey];
        if (crossing) [prev, current] = set(prev, current, `/crossing${current}`);
        [prev, current] = set(prev, current, value!, { optional: true, done: { path: '/screen', countdown: +countdown, title }, crossing });
      } else if (next) {
        [prev, current] = set(prev, current, next);
      }
    } while (config.length);
  };

  const $reset = () => {
    _flow.value = {};
  };

  const router = {
    push(path?: FlowKey) {
      path ??= flow.value?.next ?? '/screen';
      return _router.push({ path, replace: true });
    },
    done(path: FlowKey = '/screen') {
      return _router.push({ path, replace: true });
    },
    hasNext(key: FlowKey) {
      const flow = _flow.value;
      let value: FlowKey | undefined = current.value;
      do {
        const next: FlowKey | undefined = flow[value]?.next;
        console.log('log', value, next, key);
        if (next === key) return true;
        value = next;
      } while (value);
      console.log(current.value, _flow.value);
      return false;
    },
  };

  return { flow, current, router, $init, $reset };
});

/**
 * 移除虚拟节点：tongueface_upload_result
 */
function polyfill(config: string[]) {
  const index = config.findIndex((value) => value.startsWith('tongueface_upload_result'));
  if (index >= 0) {
    const prev = config[index - 1]?.startsWith('tongueface_upload');
    const next = config[index + 1];
    if (prev && next && !next.includes('?')) config.splice(index, 2, `${next}?`);
    else config.splice(index, 1);
  }
  return [...config];
}
