"use server"

import { prisma } from "@/lib/prisma"
import { z } from "zod"

/**
 * Standard action result type
 */
export type ActionResult<T = void> = {
  success: boolean
  data?: T
  message?: string
  errors?: Record<string, string[]>
}

// ============================================================================
// VALIDATION SCHEMAS
// ============================================================================

const searchHanziSchema = z.object({
  query: z.string().min(1, "Search query is required"),
  hskLevel: z.string().optional(),
  limit: z.number().int().positive().max(100).default(20),
  offset: z.number().int().min(0).default(0),
})

const getHanziSchema = z.object({
  id: z.string().min(1, "Hanzi ID is required"),
})

const getHanziBySimplifiedSchema = z.object({
  char: z.string().min(1, "Character is required"),
})

// ============================================================================
// HANZI SEARCH
// ============================================================================

/**
 * Search hanzi database (public - no authentication required)
 * Searches by simplified character, pinyin, or meaning
 */
export async function searchHanzi(
  query: string,
  hskLevel?: string,
  limit: number = 20,
  offset: number = 0
): Promise<
  ActionResult<{
    hanzi: Array<{
      id: string
      simplified: string
      traditional: string | null
      pinyin: string | null
      meaning: string | null
      hskLevels: string[]
      radical: string | null
      frequency: number | null
    }>
    total: number
    hasMore: boolean
  }>
> {
  try {
    const validation = searchHanziSchema.safeParse({ query, hskLevel, limit, offset })
    if (!validation.success) {
      return {
        success: false,
        message: "Validation failed",
        errors: validation.error.flatten().fieldErrors,
      }
    }

    // Build where clause
    const whereClause: any = {
      OR: [
        { simplified: { contains: query, mode: "insensitive" } },
        {
          forms: {
            some: {
              OR: [
                { traditional: { contains: query, mode: "insensitive" } },
                {
                  transcriptions: {
                    some: {
                      value: { contains: query, mode: "insensitive" },
                    },
                  },
                },
                {
                  meanings: {
                    some: {
                      meaning: { contains: query, mode: "insensitive" },
                    },
                  },
                },
              ],
            },
          },
        },
      ],
    }

    // Add HSK level filter if provided
    if (hskLevel) {
      whereClause.hskLevels = {
        some: {
          level: hskLevel,
        },
      }
    }

    // Get total count for pagination
    const total = await prisma.hanzi.count({ where: whereClause })

    // Get hanzi with extra for hasMore check
    const results = await prisma.hanzi.findMany({
      where: whereClause,
      include: {
        forms: {
          where: { isDefault: true },
          include: {
            transcriptions: {
              where: { type: "pinyin" },
              take: 1,
            },
            meanings: {
              orderBy: { orderIndex: "asc" },
              take: 1,
            },
          },
          take: 1,
        },
        hskLevels: {
          select: { level: true },
        },
      },
      skip: offset,
      take: limit + 1, // Take one extra to check hasMore
      orderBy: [{ frequency: "asc" }, { simplified: "asc" }],
    })

    const hasMore = results.length > limit
    const hanziList = results.slice(0, limit)

    const hanzi = hanziList.map((h) => ({
      id: h.id,
      simplified: h.simplified,
      traditional: h.forms[0]?.traditional || null,
      pinyin: h.forms[0]?.transcriptions[0]?.value || null,
      meaning: h.forms[0]?.meanings[0]?.meaning || null,
      hskLevels: h.hskLevels.map((l) => l.level),
      radical: h.radical,
      frequency: h.frequency,
    }))

    return {
      success: true,
      data: {
        hanzi,
        total,
        hasMore,
      },
    }
  } catch (error) {
    console.error("Failed to search hanzi:", error)
    return {
      success: false,
      message: "Failed to search hanzi",
    }
  }
}

/**
 * Get detailed hanzi information (public - no authentication required)
 * Returns all forms, transcriptions, meanings, HSK levels, etc.
 */
export async function getHanzi(id: string): Promise<
  ActionResult<{
    id: string
    simplified: string
    radical: string | null
    frequency: number | null
    forms: Array<{
      id: string
      traditional: string
      isDefault: boolean
      transcriptions: Array<{
        type: string
        value: string
      }>
      meanings: Array<{
        language: string
        meaning: string
        orderIndex: number
      }>
      classifiers: Array<{
        classifier: string
      }>
    }>
    hskLevels: Array<{
      level: string
    }>
    partsOfSpeech: Array<{
      pos: string
    }>
  }>
> {
  try {
    const validation = getHanziSchema.safeParse({ id })
    if (!validation.success) {
      return {
        success: false,
        message: "Validation failed",
        errors: validation.error.flatten().fieldErrors,
      }
    }

    const hanzi = await prisma.hanzi.findUnique({
      where: { id },
      include: {
        forms: {
          include: {
            transcriptions: {
              orderBy: { type: "asc" },
            },
            meanings: {
              include: {
                language: true,
              },
              orderBy: { orderIndex: "asc" },
            },
            classifiers: true,
          },
          orderBy: { isDefault: "desc" },
        },
        hskLevels: true,
        partsOfSpeech: true,
      },
    })

    if (!hanzi) {
      return {
        success: false,
        message: "Hanzi not found",
      }
    }

    const data = {
      id: hanzi.id,
      simplified: hanzi.simplified,
      radical: hanzi.radical,
      frequency: hanzi.frequency,
      forms: hanzi.forms.map((form) => ({
        id: form.id,
        traditional: form.traditional,
        isDefault: form.isDefault,
        transcriptions: form.transcriptions.map((t) => ({
          type: t.type,
          value: t.value,
        })),
        meanings: form.meanings.map((m) => ({
          language: m.language.code,
          meaning: m.meaning,
          orderIndex: m.orderIndex,
        })),
        classifiers: form.classifiers.map((c) => ({
          classifier: c.classifier,
        })),
      })),
      hskLevels: hanzi.hskLevels.map((l) => ({
        level: l.level,
      })),
      partsOfSpeech: hanzi.partsOfSpeech.map((p) => ({
        pos: p.pos,
      })),
    }

    return {
      success: true,
      data,
    }
  } catch (error) {
    console.error("Failed to get hanzi:", error)
    return {
      success: false,
      message: "Failed to get hanzi details",
    }
  }
}

/**
 * Get hanzi by simplified character (public - no authentication required)
 * Quick lookup by simplified character
 */
export async function getHanziBySimplified(char: string): Promise<
  ActionResult<{
    id: string
    simplified: string
    traditional: string | null
    pinyin: string | null
    meaning: string | null
    hskLevels: string[]
  }>
> {
  try {
    const validation = getHanziBySimplifiedSchema.safeParse({ char })
    if (!validation.success) {
      return {
        success: false,
        message: "Validation failed",
        errors: validation.error.flatten().fieldErrors,
      }
    }

    const hanzi = await prisma.hanzi.findUnique({
      where: { simplified: char },
      include: {
        forms: {
          where: { isDefault: true },
          include: {
            transcriptions: {
              where: { type: "pinyin" },
              take: 1,
            },
            meanings: {
              orderBy: { orderIndex: "asc" },
              take: 1,
            },
          },
          take: 1,
        },
        hskLevels: {
          select: { level: true },
        },
      },
    })

    if (!hanzi) {
      return {
        success: false,
        message: "Hanzi not found",
      }
    }

    const data = {
      id: hanzi.id,
      simplified: hanzi.simplified,
      traditional: hanzi.forms[0]?.traditional || null,
      pinyin: hanzi.forms[0]?.transcriptions[0]?.value || null,
      meaning: hanzi.forms[0]?.meanings[0]?.meaning || null,
      hskLevels: hanzi.hskLevels.map((l) => l.level),
    }

    return {
      success: true,
      data,
    }
  } catch (error) {
    console.error("Failed to get hanzi by simplified:", error)
    return {
      success: false,
      message: "Failed to get hanzi",
    }
  }
}
