import type { RowDataPacket, ResultSetHeader } from 'mysql2'
import { db, DB } from './db'

export interface PromoCode {
  id: number
  code: string
  pd: number
  pv: number
  max_uses: number
  uses: number
  active: number
  expires_at: string | null
  redemptions: number
}

/** Normaliza un valor datetime-local ("YYYY-MM-DDTHH:MM") a DATETIME de MySQL, o null. */
function toMysqlDate(v: string): string | null {
  const s = v.trim()
  if (!s) return null
  return s.replace('T', ' ').slice(0, 19)
}

export async function listPromoCodes(): Promise<PromoCode[]> {
  const [rows] = await db(DB.default).query<RowDataPacket[]>(
    `SELECT p.id, p.code, p.pd, p.pv, p.max_uses, p.uses, p.active, p.expires_at,
            (SELECT COUNT(*) FROM promoredemption r WHERE r.promo_id = p.id) AS redemptions
       FROM promocode p ORDER BY p.id DESC`,
  )
  return rows.map((r) => ({
    id: r.id,
    code: r.code,
    pd: r.pd,
    pv: r.pv,
    max_uses: r.max_uses,
    uses: r.uses,
    active: r.active,
    expires_at: r.expires_at ? new Date(r.expires_at).toISOString() : null,
    redemptions: Number(r.redemptions),
  }))
}

export async function createPromoCode(
  code: string,
  pd: number,
  pv: number,
  maxUses: number,
  expiresAt: string,
): Promise<{ id?: number; error?: string }> {
  try {
    const [res] = await db(DB.default).query<ResultSetHeader>(
      'INSERT INTO promocode (code, pd, pv, max_uses, uses, active, expires_at, created_at) VALUES (?, ?, ?, ?, 0, 1, ?, NOW())',
      [code, pd, pv, maxUses, toMysqlDate(expiresAt)],
    )
    return { id: res.insertId }
  } catch (e) {
    if ((e as { code?: string }).code === 'ER_DUP_ENTRY') return { error: 'duplicate' }
    return { error: 'genericError' }
  }
}

export async function updatePromoCode(
  id: number,
  fields: { pd: number; pv: number; maxUses: number; active: boolean },
): Promise<void> {
  await db(DB.default).query(
    'UPDATE promocode SET pd = ?, pv = ?, max_uses = ?, active = ? WHERE id = ?',
    [fields.pd, fields.pv, fields.maxUses, fields.active ? 1 : 0, id],
  )
}

export async function deletePromoCode(id: number): Promise<void> {
  await db(DB.default).query('DELETE FROM promoredemption WHERE promo_id = ?', [id])
  await db(DB.default).query('DELETE FROM promocode WHERE id = ?', [id])
}
