import { i18n } from '@/i18n'
import localforage from 'localforage'

export type WorkspaceMode =  'project' | 'quick'

export const PROJECT_TAB_ID = 'ProjectCalcView'
export const QUICK_TAB_ID = 'QuickCalcView'
export const LEGACY_PROJECT_TAB_ID = 'ProjectCalcView'
export const FIXED_WORKSPACE_TAB_IDS = [PROJECT_TAB_ID, QUICK_TAB_ID] as const

export const WORKSPACE_MODE_STORAGE_KEY = 'jgjs-workspace-mode-v1'
export const PROJECT_ID_QUERY_KEY = 'projectId'
export const NEW_PROJECT_QUERY_KEY = 'newProject'
export const OPEN_PROJECT_DIALOG_QUERY_KEY = 'openProjectDialog'
export const FORCE_HOME_QUERY_KEY = 'forceHome'
export const DEFAULT_PROJECT_ID = 'default'
export const QUICK_PROJECT_ID = 'quick'
export const PROJECT_DB_NAME_PREFIX = 'DB'

export const QUICK_CONTRACT_ID = 'quick-contract-default'
export const QUICK_CONTRACT_META_KEY = 'quick-contract-meta-v1'
export const QUICK_CONTRACT_FALLBACK_NAME = i18n.global.t('quickCalc.projectName')
export const QUICK_CONTRACT_TAB_ID = `contract-${QUICK_CONTRACT_ID}`

export const QUICK_PROJECT_INFO_KEY = 'quick-xm-base-info-v1'
export const QUICK_PROJECT_SCALE_KEY = 'quick-xm-info-v3'
export const QUICK_CONSULT_CATEGORY_FACTOR_KEY = 'quick-xm-consult-category-factor-v1'
export const QUICK_MAJOR_FACTOR_KEY = 'quick-xm-major-factor-v1'

const HOME_IMPORT_TEMP_DB_NAME = 'JGJS-HOME-IMPORT-TEMP'
const HOME_IMPORT_TEMP_STORE_NAME = 'home-import'
const HOME_IMPORT_TEMP_FILE_KEY = 'pending-file'
const HOME_IMPORT_SKIP_CONFIRM_KEY = 'jgjs-home-import-skip-confirm'
const homeImportTempForage = localforage.createInstance({
  name: HOME_IMPORT_TEMP_DB_NAME,
  storeName: HOME_IMPORT_TEMP_STORE_NAME
})

export interface QuickContractMeta {
  id: string
  name: string
  updatedAt: string
}



export const readWorkspaceMode = (): WorkspaceMode => {
  try {
    return window.localStorage.getItem(WORKSPACE_MODE_STORAGE_KEY)  as WorkspaceMode 
  } catch {
    return 'project'
  }
}



export const createDefaultQuickContractMeta = (): QuickContractMeta => ({
  id: QUICK_CONTRACT_ID,
  name: QUICK_CONTRACT_FALLBACK_NAME,
  updatedAt: new Date().toISOString()
})
export const writeWorkspaceMode = (mode: WorkspaceMode) => {
  try {
    window.localStorage.setItem(WORKSPACE_MODE_STORAGE_KEY, mode)
  } catch {
    // 忽略只读或隐私模式下的写入失败。
  }
}

export const setPendingHomeImportFile = (
  file: File | null,
  options?: { skipWorkspaceConfirm?: boolean }
) => {
  return (async () => {
    try {
      if (file) {
        await homeImportTempForage.setItem(HOME_IMPORT_TEMP_FILE_KEY, {
          name: file.name,
          type: file.type,
          lastModified: file.lastModified,
          blob: file
        })
      } else {
        await homeImportTempForage.removeItem(HOME_IMPORT_TEMP_FILE_KEY)
      }
    } catch {
      // ignore temp file persistence errors
    }
    try {
      window.sessionStorage.setItem(HOME_IMPORT_SKIP_CONFIRM_KEY, options?.skipWorkspaceConfirm ? '1' : '0')
    } catch {
      // ignore session storage errors
    }
  })()
}

export const consumePendingHomeImportFile = async () => {
  try {
    const payload = await homeImportTempForage.getItem<{
      name?: string
      type?: string
      lastModified?: number
      blob?: Blob
    }>(HOME_IMPORT_TEMP_FILE_KEY)
    await homeImportTempForage.removeItem(HOME_IMPORT_TEMP_FILE_KEY)
    if (!payload?.blob) return null
    const name = String(payload.name || 'import.zw').trim() || 'import.zw'
    return new File([payload.blob], name, {
      type: typeof payload.type === 'string' ? payload.type : '',
      lastModified: typeof payload.lastModified === 'number' ? payload.lastModified : Date.now()
    })
  } catch {
    return null
  }
}

export const consumePendingHomeImportSkipConfirm = () => {
  try {
    const skip = window.sessionStorage.getItem(HOME_IMPORT_SKIP_CONFIRM_KEY) === '1'
    window.sessionStorage.removeItem(HOME_IMPORT_SKIP_CONFIRM_KEY)
    return skip
  } catch {
    return false
  }
}

export const normalizeProjectId = (value: unknown) => {
  const raw = String(value || '').trim()
  if (!raw) return DEFAULT_PROJECT_ID
  return raw.replace(/[^a-zA-Z0-9_-]/g, '').slice(0, 64) || DEFAULT_PROJECT_ID
}

export const readCurrentProjectId = () => {
  try {
    const url = new URL(window.location.href)
    return normalizeProjectId(url.searchParams.get(PROJECT_ID_QUERY_KEY))
  } catch {
    return DEFAULT_PROJECT_ID
  }
}

export const writeProjectIdToUrl = (projectIdRaw: string) => {
  try {
    const projectId = normalizeProjectId(projectIdRaw)
    const url = new URL(window.location.href)
    url.searchParams.set(PROJECT_ID_QUERY_KEY, projectId)
    window.history.replaceState({}, '', `${url.pathname}${url.search}${url.hash}`)
  } catch (error) {
    console.error('write project id to url failed:', error)
  }
}

export const ensureProjectIdInUrl = () => {
  const id = readCurrentProjectId()
  writeProjectIdToUrl(id)
  return id
}

export const buildProjectUrl = (
  projectIdRaw: string,
  options?: { newProject?: boolean; openProjectDialog?: boolean; forceHome?: boolean }
) => {
  try {
    const url = new URL(window.location.href)
    url.searchParams.set(PROJECT_ID_QUERY_KEY, normalizeProjectId(projectIdRaw))
    if (options?.newProject) {
      url.searchParams.set(NEW_PROJECT_QUERY_KEY, '1')
      if (options?.openProjectDialog === false) {
        url.searchParams.set(OPEN_PROJECT_DIALOG_QUERY_KEY, '0')
      } else {
        url.searchParams.delete(OPEN_PROJECT_DIALOG_QUERY_KEY)
      }
    } else {
      url.searchParams.delete(NEW_PROJECT_QUERY_KEY)
      url.searchParams.delete(OPEN_PROJECT_DIALOG_QUERY_KEY)
    }
    if (options?.forceHome) {
      url.searchParams.set(FORCE_HOME_QUERY_KEY, '1')
    } else {
      url.searchParams.delete(FORCE_HOME_QUERY_KEY)
    }
    return `${url.pathname}${url.search}${url.hash}`
  } catch {
    return `/?${PROJECT_ID_QUERY_KEY}=${encodeURIComponent(normalizeProjectId(projectIdRaw))}`
  }
}

export const getProjectDbName = (projectIdRaw: string) => {
  const projectId = normalizeProjectId(projectIdRaw)
  return `${PROJECT_DB_NAME_PREFIX}-${projectId}`
}
