import { generateUUID } from "@/helpers/uuid.helper"
import prisma from "@/lib/prismadb"
import { Prisma } from "@prisma/client"
import type { NextApiRequest, NextApiResponse } from "next"

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
  if (req.method === "GET") {
    return get(req, res)
  } else if (req.method === "POST") {
    return create(req, res)
  } else {
    return res.status(405).json({ error: "Method not allowed" })
  }
}

async function get(req: NextApiRequest, res: NextApiResponse) {
  console.log("req.query", req.query)

  const accesstoken = req.query.accesstoken ? (req.query.accesstoken as string) : ""
  const tag = typeof req.query.tag === "string" ? req.query.tag : undefined
  const q = typeof req.query.q === "string" ? req.query.q : undefined
  const page = req.query.page ? Number(req.query.page) : 1
  const pageSize = req.query.limit ? Number(req.query.limit) : 10
  const start = (page - 1) * pageSize

  let conditions = Prisma.sql``

  if (tag) {
    conditions = Prisma.sql`${conditions} AND p.tag LIKE ${"%" + tag + "%"}`
  }

  if (q) {
    conditions = Prisma.sql`${conditions}
      AND (p.tag LIKE ${"%" + q + "%"}
          OR p.subject LIKE ${"%" + q + "%"}
          OR p.content LIKE ${"%" + q + "%"})`
  }

  const query = Prisma.sql`
    SELECT p.id, p.course, p.subject, p.content, p.tag, p.status, p.publish_at, IFNULL(q.cnt, 0) AS cnt
    FROM program p
    LEFT JOIN (SELECT program_id, COUNT(*) AS cnt FROM quiz GROUP BY program_id) q ON p.id = q.program_id
    WHERE TRUE ${conditions}
    ORDER BY p.created_at DESC
    LIMIT ${pageSize} OFFSET ${start}
`
  const result = await prisma.$queryRaw<any[]>(query)

  const totalQuery = Prisma.sql`
    SELECT CAST(COUNT(*) AS UNSIGNED) AS cnt
    FROM program p
    WHERE TRUE ${conditions}
  `

  type CountResult = { cnt: bigint }
  const totalResult: CountResult[] = await prisma.$queryRaw<CountResult[]>(totalQuery)
  const total: number = Number(totalResult.length > 0 ? totalResult[0].cnt : 0)
  const totalPage = Math.ceil(Number(total / pageSize))

  const data = JSON.parse(
    JSON.stringify(result, (key, value) => (typeof value === "bigint" ? value.toString() : value))
  )

  res.status(200).json({
    message: "OK",
    data: data,
    page: page,
    pageSize: pageSize,
    totalPage: totalPage,
    total: total,
    start: start,
  })
}

async function create(req: NextApiRequest, res: NextApiResponse) {
  const { course, subject, content, tag, status, publish_at } = req.body
  let id = generateUUID()
  const result = await prisma.program.create({
    data: {
      id,
      course,
      subject,
      content,
      tag,
      status,
      publish_at,
    },
  })

  if (!result) {
    return res.status(400).json({ error: "create fail" })
  }

  return res.status(200).json(result)
}
