import type { ActionState } from "@/shared/types/action-state"

export type AnnouncementStatus = "draft" | "published" | "archived"

export type AnnouncementType = "school" | "grade" | "class"

export interface Announcement {
  id: string
  title: string
  content: string
  type: AnnouncementType
  status: AnnouncementStatus
  targetGradeId: string | null
  targetClassId: string | null
  authorId: string
  authorName: string | null
  publishedAt: string | null
  isPinned: boolean
  /** V2-P2-13d: 当前用户是否已读（仅用户端查询时填充） */
  isReadByCurrentUser?: boolean
  /** V2-P2-13d: 已读人数（仅管理端查询时填充） */
  readCount?: number
  createdAt: string
  updatedAt: string
}

export type AnnouncementListItem = Announcement

export type GetAnnouncementsParams = {
  status?: AnnouncementStatus
  type?: AnnouncementType
  page?: number
  pageSize?: number
  /**
   * 受众过滤（用户端使用）：当提供时，仅返回对该受众可见的公告。
   * - school 类型公告：对所有受众可见
   * - grade 类型公告：仅当 targetGradeId ∈ audience.gradeIds 时可见
   * - class 类型公告：仅当 targetClassId ∈ audience.classIds 时可见
   *
   * P0-2 修复：从单值 `{ gradeId?, classId? }` 升级为数组，
   * 解决家长多孩子 / 教师多班级 / 年级主任多年级时只能看到首个受众的截断 Bug。
   * 未提供时（管理端）返回所有公告。
   */
  audience?: {
    gradeIds: string[]
    classIds: string[]
  }
}

/**
 * 用户受众信息（P0-2 新增）。
 * 由 data-access 的 `resolveUserAudience` 解析得到，
 * 用于公告可见性判断与列表过滤。
 */
export interface UserAudience {
  gradeIds: string[]
  classIds: string[]
}

export interface AnnouncementInsertData {
  id: string
  title: string
  content: string
  type: AnnouncementType
  status: AnnouncementStatus
  targetGradeId: string | null
  targetClassId: string | null
  authorId: string
  publishedAt: Date | null
}

export interface AnnouncementUpdateData {
  title: string
  content: string
  type: AnnouncementType
  status: AnnouncementStatus
  targetGradeId: string | null
  targetClassId: string | null
  publishedAt: Date | null
  updatedAt: Date
}

/** V2-P2-13d: 公告已读回执 */
export interface AnnouncementRead {
  id: string
  announcementId: string
  userId: string
  readAt: string
}

/**
 * P2-6: 分页查询结果。
 *
 * 由 `getUserAnnouncementsPageData` 与 `getAdminAnnouncementsPageData` 返回，
 * 供 `AnnouncementPagination` 组件计算页码与上一页/下一页导航。
 */
export interface PaginatedAnnouncements {
  items: Announcement[]
  total: number
  page: number
  pageSize: number
}

/**
 * P1-3: 公告服务接口（依赖注入抽象）。
 *
 * 组件层通过 `useAnnouncementsService()` 消费此接口，而非直接 import actions，
 * 实现完全解耦：
 * - 默认实现调用真实 Server Actions（见 `default-announcements-service.ts`）
 * - 测试时可注入 mock 实现
 * - 未来不同角色可注入不同实现（如家长只读、教师可编辑班级公告）
 *
 * 所有方法返回 `ActionState`，与 Server Action 签名保持一致，便于无缝替换。
 */
export interface AnnouncementsService {
  create(prevState: ActionState<string> | null, formData: FormData): Promise<ActionState<string>>
  update(id: string, prevState: ActionState<string> | null, formData: FormData): Promise<ActionState<string>>
  delete(id: string): Promise<ActionState<string>>
  publish(id: string): Promise<ActionState<string>>
  archive(id: string): Promise<ActionState<string>>
  togglePin(id: string): Promise<ActionState<string>>
  markRead(announcementId: string): Promise<ActionState<string>>
  getReadStatus(announcementIds: string[]): Promise<ActionState<Record<string, boolean>>>
}
