"use client"

import { createContext, useContext, type ReactNode } from "react"

import type {
  AuditLog,
  AuditLogQueryParams,
  AuditOverviewStats,
  AuditRetentionConfig,
  AuditTrendPoint,
  DataChangeActionStat,
  DataChangeLog,
  DataChangeLogQueryParams,
  DataChangeStat,
  LoginLog,
  LoginLogQueryParams,
  PaginatedResult,
  PurgeResult,
} from "@/modules/audit/types"

// ─── 数据服务接口 ──────────────────────────────────────────

/**
 * 审计数据服务接口（抽象数据依赖）。
 *
 * 定义所有审计模块数据获取与操作的契约。
 * 组件通过 `useAuditService()` 获取当前注入的实现，不直接 import data-access。
 * 测试时可注入 mock 实现以隔离数据层。
 *
 * 角色差异通过不同实现隔离：
 * - AdminAuditService：完整访问（默认实现，委托给 data-access）
 * - 未来 ComplianceAuditService：只读子集
 */
export interface AuditService {
  // ── 日志查询 ──
  getAuditLogs(params?: AuditLogQueryParams): Promise<PaginatedResult<AuditLog>>
  getLoginLogs(params?: LoginLogQueryParams): Promise<PaginatedResult<LoginLog>>
  getDataChangeLogs(params?: DataChangeLogQueryParams): Promise<PaginatedResult<DataChangeLog>>

  // ── 选项与统计 ──
  getAuditModuleOptions(): Promise<string[]>
  getDataChangeStats(): Promise<DataChangeStat[]>
  getDataChangeTableOptions(): Promise<string[]>

  // ── 概览仪表盘 ──
  getAuditOverviewStats(): Promise<AuditOverviewStats>
  getAuditTrend(days?: number): Promise<AuditTrendPoint[]>
  getDataChangeActionStats(): Promise<DataChangeActionStat[]>

  // ── 保留策略 ──
  getAuditRetentionConfig(): Promise<AuditRetentionConfig>
  saveAuditRetentionConfig(config: AuditRetentionConfig): Promise<void>
  purgeExpiredAuditLogs(retentionDays: number, loginLogRetentionDays?: number): Promise<PurgeResult>
}

// ─── 监控埋点接口 ──────────────────────────────────────────

/**
 * 审计监控埋点接口。
 *
 * 预留关键操作埋点，供后续接入实际监控 SDK（如 PostHog / Mixpanel）。
 * 默认实现为空操作，生产环境通过 Provider 注入实际实现。
 */
export interface AuditAnalytics {
  /** 日志查看 */
  trackLogView(logType: "audit" | "login" | "dataChange"): void
  /** 日志导出 */
  trackExport(logType: "audit" | "login" | "dataChange", count: number): void
  /** 保留策略变更 */
  trackRetentionConfigChange(config: AuditRetentionConfig): void
  /** 手动清理 */
  trackPurge(result: PurgeResult): void
  /** 概览页查看 */
  trackOverviewView(): void
}

/** 空操作实现（默认） */
const noopAnalytics: AuditAnalytics = {
  trackLogView: () => {},
  trackExport: () => {},
  trackRetentionConfigChange: () => {},
  trackPurge: () => {},
  trackOverviewView: () => {},
}

// ─── React Context 依赖注入 ────────────────────────────────

const AuditServiceContext = createContext<AuditService | null>(null)
const AuditAnalyticsContext = createContext<AuditAnalytics>(noopAnalytics)

/**
 * 审计服务 Provider（在页面层注入角色特定的实现）。
 *
 * @example
 * ```tsx
 * <AuditServiceProvider service={adminAuditService}>
 *   <AuditOverviewView ... />
 * </AuditServiceProvider>
 * ```
 */
export function AuditServiceProvider({
  service,
  analytics,
  children,
}: {
  service: AuditService
  analytics?: AuditAnalytics
  children: ReactNode
}): ReactNode {
  return (
    <AuditServiceContext.Provider value={service}>
      <AuditAnalyticsContext.Provider value={analytics ?? noopAnalytics}>
        {children}
      </AuditAnalyticsContext.Provider>
    </AuditServiceContext.Provider>
  )
}

/**
 * 获取当前注入的审计数据服务。
 *
 * 必须在 `AuditServiceProvider` 内部使用。
 */
export function useAuditService(): AuditService {
  const service = useContext(AuditServiceContext)
  if (!service) {
    throw new Error("useAuditService must be used within AuditServiceProvider")
  }
  return service
}

/**
 * 获取当前注入的审计监控埋点接口。
 *
 * 未注入时返回空操作实现，安全调用。
 */
export function useAuditAnalytics(): AuditAnalytics {
  return useContext(AuditAnalyticsContext)
}
