import type { InjectionKey, Ref, ComputedRef } from 'vue'
import { useRoute } from 'vue-router'
import deptApi from '@/api/system/dept'
import { router } from '@/router'
import { useUserStore } from '@/store/modules/user'
import {
  isAllChannelScopeRoute,
  isConfigChannelRoute,
  isNoChannelLayoutRoute,
  isRoleChannelRoute,
  isSuperAdminUser
} from '@/utils/channelLayout'

export interface ChannelTreeNode {
  id: number
  label: string
  children?: ChannelTreeNode[]
}

/** 默认配置模板（dept_id = 0） */
export const DEFAULT_CHANNEL_ID = 0

export interface ChannelDeptScopeContext {
  treeData: Ref<ChannelTreeNode[]>
  selectedDeptId: Ref<number>
  loadingChannels: Ref<boolean>
  isSuperAdmin: Ref<boolean>
  selectedDeptLabel: Ref<string>
  deptQueryParams: ComputedRef<{ dept_id: number }>
  isConfigScope: ComputedRef<boolean>
  isAllChannelScope: ComputedRef<boolean>
  showDefaultTemplate: ComputedRef<boolean>
}

export const CHANNEL_DEPT_SCOPE_KEY: InjectionKey<ChannelDeptScopeContext> =
  Symbol('channelDeptScope')

/**
 * 当前应用中处于激活态的超管渠道上下文。
 * 仅有一个 SuperAdminChannelShell 实例，所以可以在模块作用域内缓存其 ctx，
 * 供 setInterval / 异步回调 / 事件处理器等"setup 外"路径取用——
 * 这些路径上 Vue 的 inject() 会失效（getCurrentInstance() 为 null）。
 */
let activeChannelCtx: ChannelDeptScopeContext | null = null

export function provideChannelDeptScope(ctx: ChannelDeptScopeContext) {
  provide(CHANNEL_DEPT_SCOPE_KEY, ctx)
  activeChannelCtx = ctx
  onScopeDispose(() => {
    if (activeChannelCtx === ctx) {
      activeChannelCtx = null
    }
  })
}

export function useInjectedChannelDept(): ChannelDeptScopeContext | null {
  // 仅在组件 setup 同步路径下调用 inject() 才可靠；
  // 否则（异步回调、setInterval、事件处理器等）退化为读取模块级激活上下文，
  // 避免渠道切换后 getCurrentPool/withChannelDeptParams 等仍按超管自身部门发请求。
  if (getCurrentInstance()) {
    const ctx = inject(CHANNEL_DEPT_SCOPE_KEY, null)
    if (ctx) {
      return ctx
    }
  }
  return activeChannelCtx
}

/** 超管全局渠道栏：创建并 provide 渠道上下文 */
export function useChannelDeptScope() {
  const route = useRoute()
  const userStore = useUserStore()
  const treeData = ref<ChannelTreeNode[]>([])
  const selectedDeptId = ref<number>(DEFAULT_CHANNEL_ID)
  const loadingChannels = ref(false)

  const isConfigScope = computed(() => isConfigChannelRoute(route))
  const isRoleScope = computed(() => isRoleChannelRoute(route))
  const isAllChannelScope = computed(() => isAllChannelScopeRoute(route))
  const showDefaultTemplate = computed(() => isConfigScope.value || isRoleScope.value)

  const isSuperAdmin = computed(() => isSuperAdminUser())

  const selectedDeptLabel = computed(() => {
    const find = (nodes: ChannelTreeNode[]): string => {
      for (const n of nodes) {
        if (n.id === selectedDeptId.value) {
          return n.label
        }
        if (n.children?.length) {
          const sub = find(n.children)
          if (sub) return sub
        }
      }
      return ''
    }
    return find(treeData.value)
  })

  const deptQueryParams = computed(() => {
    const id = selectedDeptId.value
    if (isAllChannelScope.value && id <= 0) {
      return { dept_id: 0 }
    }
    if (!showDefaultTemplate.value && id <= 0) {
      return { dept_id: 0 }
    }
    return { dept_id: id }
  })

  const loadChannels = async () => {
    loadingChannels.value = true
    try {
      const list = await deptApi.accessDept()
      const channels = Array.isArray(list) ? list : []
      const nodes: ChannelTreeNode[] = channels.map((item: Record<string, unknown>) => ({
        id: Number(item.id ?? item.value),
        label: String(item.label ?? item.name ?? item.id)
      }))
      if (isSuperAdmin.value) {
        if (showDefaultTemplate.value || isAllChannelScope.value) {
          treeData.value = [{ id: DEFAULT_CHANNEL_ID, label: '' }, ...nodes]
          if (!treeData.value.some((n) => n.id === selectedDeptId.value)) {
            selectedDeptId.value = DEFAULT_CHANNEL_ID
          }
        } else {
          treeData.value = nodes
          if (nodes.length > 0) {
            const valid = nodes.some((n) => n.id === selectedDeptId.value)
            if (!valid || selectedDeptId.value <= 0) {
              selectedDeptId.value = nodes[0].id
            }
          }
        }
      } else {
        treeData.value = nodes
        if (nodes.length > 0) {
          selectedDeptId.value = nodes[0].id
        }
      }
    } finally {
      loadingChannels.value = false
    }
  }

  const handleChannelClick = (data: ChannelTreeNode) => {
    selectedDeptId.value = Number(data.id)
  }

  const ctx: ChannelDeptScopeContext = {
    treeData,
    selectedDeptId,
    loadingChannels,
    isSuperAdmin,
    selectedDeptLabel,
    deptQueryParams,
    isConfigScope,
    isAllChannelScope,
    showDefaultTemplate
  }

  onMounted(() => {
    loadChannels()
  })

  return {
    ...ctx,
    loadChannels,
    handleChannelClick,
    provideScope: () => provideChannelDeptScope(ctx)
  }
}

/** 将当前选中渠道写入列表查询参数并刷新 */
export function bindChannelDeptToSearchParams(
  searchParams: Record<string, unknown>,
  refresh: () => void,
  options?: { immediate?: boolean; enabled?: boolean }
) {
  const channel = useInjectedChannelDept()
  if (!channel || options?.enabled === false) {
    return
  }

  const apply = (deptId: number) => {
    if (channel.isAllChannelScope.value && deptId <= 0) {
      delete searchParams.dept_id
      refresh()
      return
    }
    if (!channel.showDefaultTemplate.value && deptId <= 0) {
      return
    }
    searchParams.dept_id = deptId
    refresh()
  }

  watch(
    () => channel.selectedDeptId.value,
    (deptId) => apply(deptId),
    { immediate: options?.immediate ?? true }
  )
}

/** 工作台等非 useTable 页面：渠道切换时重新拉数 */
export function useChannelDeptReload(loadFn: () => void | Promise<void>) {
  const channel = useInjectedChannelDept()
  if (!channel) {
    onMounted(() => {
      void loadFn()
    })
    return
  }

  watch(
    () => channel.selectedDeptId.value,
    (deptId) => {
      if (channel.isAllChannelScope.value && deptId <= 0) {
        void loadFn()
        return
      }
      if (!channel.showDefaultTemplate.value && deptId <= 0) {
        return
      }
      void loadFn()
    },
    { immediate: true }
  )
}

/** 请求参数：业务页附带 dept_id；渠道管理员固定本渠道 */
export function getChannelDeptRequestParams(): { dept_id?: number } {
  const channel = useInjectedChannelDept()
  const route = getCurrentInstance() ? useRoute() : router.currentRoute.value
  if (isNoChannelLayoutRoute(route)) {
    return {}
  }
  if (channel?.isSuperAdmin.value) {
    const deptId = channel.selectedDeptId.value
    if (channel.isAllChannelScope.value && deptId <= 0) {
      return {}
    }
    if (!channel.showDefaultTemplate.value && deptId <= 0) {
      return {}
    }
    if (deptId > 0) {
      return { dept_id: deptId }
    }
    if (channel.showDefaultTemplate.value) {
      return { dept_id: deptId }
    }
    return {}
  }

  const userStore = useUserStore()
  const dept = userStore.info?.department
  if (dept && Number(dept.id) > 0) {
    return { dept_id: Number(dept.id) }
  }

  return {}
}

/** 保存/更新时附带 dept_id（优先渠道栏选中值，其次表单/行数据中的 dept_id） */
export function withChannelDeptParams<T extends Record<string, unknown>>(payload: T): T {
  const extra = getChannelDeptRequestParams()
  if ('dept_id' in extra) {
    return { ...payload, ...extra }
  }
  const rowDeptId = payload.dept_id
  if (rowDeptId !== undefined && rowDeptId !== null && rowDeptId !== '') {
    const num = Number(rowDeptId)
    if (num > 0) {
      return { ...payload, dept_id: num }
    }
  }
  const channel = useInjectedChannelDept()
  if (channel && channel.selectedDeptId.value > 0) {
    return { ...payload, dept_id: channel.selectedDeptId.value }
  }
  return payload
}
