import "server-only"

import { and, eq, inArray, type SQL } from "drizzle-orm"

import { db } from "@/shared/db"
import { roles, users, usersToRoles } from "@/shared/db/schema"
import type { DataScope } from "@/shared/types/permissions"
import { exportToExcel, generateTemplate } from "@/shared/lib/excel"

const VALID_ROLES = ["admin", "teacher", "student", "parent", "grade_head", "teaching_head"] as const
type ValidRole = (typeof VALID_ROLES)[number]

const isValidRole = (v: string): v is ValidRole =>
  // as 断言：readonly tuple 的 includes 不接受 string 入参，需放宽为数组类型才能调用
  (VALID_ROLES as readonly string[]).includes(v.trim().toLowerCase())

export type UserImportRecord = {
  name: string
  email: string
  role: string
  phone?: string
  invitationCode?: string
}

export type UserImportValidation = {
  valid: UserImportRecord[]
  invalid: Array<{ row: number; record: UserImportRecord; errors: string[] }>
}

/**
 * 生成用户导入模板
 */
export async function generateUserImportTemplate(): Promise<Buffer> {
  return generateTemplate({
    sheets: [
      {
        name: "Users",
        columns: [
          { header: "姓名", key: "name", width: 20, note: "必填，用户姓名" },
          { header: "邮箱", key: "email", width: 28, note: "必填，唯一，登录账号" },
          { header: "角色", key: "role", width: 16, note: "必填，可选: admin/teacher/student/parent/grade_head/teaching_head" },
          { header: "手机", key: "phone", width: 18, note: "选填" },
          { header: "班级邀请码", key: "invitationCode", width: 16, note: "选填，仅 student 角色有效，6 位邀请码" },
        ],
        sampleRows: [
          { name: "张三", email: "zhangsan@example.com", role: "student", phone: "13800138000", invitationCode: "ABC123" },
          { name: "李老师", email: "li@example.com", role: "teacher", phone: "13900139000" },
        ],
      },
    ],
  })
}

/**
 * 解析并验证导入数据
 */
export function parseUserImportData(
  rows: Record<string, unknown>[]
): UserImportValidation {
  const valid: UserImportRecord[] = []
  const invalid: UserImportValidation["invalid"] = []

  rows.forEach((row, idx) => {
    const record: UserImportRecord = {
      name: String(row["姓名"] ?? row["name"] ?? "").trim(),
      email: String(row["邮箱"] ?? row["email"] ?? "").trim().toLowerCase(),
      role: String(row["角色"] ?? row["role"] ?? "").trim().toLowerCase(),
      phone: String(row["手机"] ?? row["phone"] ?? "").trim() || undefined,
      invitationCode: String(row["班级邀请码"] ?? row["invitationCode"] ?? "").trim() || undefined,
    }

    const errors: string[] = []
    if (!record.name) errors.push("姓名不能为空")
    if (!record.email) errors.push("邮箱不能为空")
    else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(record.email)) errors.push("邮箱格式无效")
    if (!record.role) errors.push("角色不能为空")
    else if (!isValidRole(record.role)) errors.push(`角色无效，可选: ${VALID_ROLES.join("/")}`)
    if (record.invitationCode && record.role !== "student") {
      errors.push("仅 student 角色可使用班级邀请码")
    }

    if (errors.length > 0) {
      invalid.push({ row: idx + 2, record, errors })
    } else {
      valid.push(record)
    }
  })

  return { valid, invalid }
}

/**
 * 导出用户列表到 Excel
 */
export async function exportUsersToExcel(params: {
  scope: DataScope
  role?: string
}): Promise<Buffer> {
  const conditions: SQL[] = []
  if (params.role) {
    const roleRows = await db
      .select({ id: roles.id })
      .from(roles)
      .where(eq(roles.name, params.role))
    if (roleRows.length > 0) {
      const userIds = await db
        .select({ userId: usersToRoles.userId })
        .from(usersToRoles)
        .where(eq(usersToRoles.roleId, roleRows[0].id))
      if (userIds.length > 0) {
        conditions.push(inArray(users.id, userIds.map((u) => u.userId)))
      } else {
        conditions.push(eq(users.id, "__none__"))
      }
    }
  }

  const userRows = await db
    .select({
      id: users.id,
      name: users.name,
      email: users.email,
      phone: users.phone,
      gender: users.gender,
      age: users.age,
      createdAt: users.createdAt,
    })
    .from(users)
    .where(conditions.length > 0 ? and(...conditions) : undefined)

  // Fetch roles for all users
  const userIds = userRows.map((u) => u.id)
  const roleLinks = userIds.length > 0
    ? await db
        .select({ userId: usersToRoles.userId, roleName: roles.name })
        .from(usersToRoles)
        .innerJoin(roles, eq(usersToRoles.roleId, roles.id))
        .where(inArray(usersToRoles.userId, userIds))
    : []
  const userRoles = new Map<string, string[]>()
  for (const link of roleLinks) {
    const arr = userRoles.get(link.userId) ?? []
    arr.push(link.roleName)
    userRoles.set(link.userId, arr)
  }

  const rows = userRows.map((u) => ({
    name: u.name ?? "",
    email: u.email,
    phone: u.phone ?? "",
    gender: u.gender ?? "",
    age: u.age ?? "",
    roles: (userRoles.get(u.id) ?? []).join(", "),
    createdAt: u.createdAt.toISOString().split("T")[0],
  }))

  return exportToExcel({
    sheets: [
      {
        name: "Users",
        columns: [
          { header: "姓名", key: "name", width: 20 },
          { header: "邮箱", key: "email", width: 28 },
          { header: "手机", key: "phone", width: 18 },
          { header: "性别", key: "gender", width: 10 },
          { header: "年龄", key: "age", width: 8 },
          { header: "角色", key: "roles", width: 24 },
          { header: "创建时间", key: "createdAt", width: 14 },
        ],
        rows,
      },
    ],
  })
}

// Re-export 保持向后兼容：用户创建与班级注册已拆分至独立文件
export { batchImportUsers, type UserImportResult } from "./user-service"
