/** Post-chat satisfaction rating (1-5) plus an optional free-text comment. */
import { many, one } from '../../db/pool.js';
import { badRequest, notFound } from '../../utils/errors.js';
import type { CsatDTO } from '../types.js';

export async function submitCsat(
  conversationId: string,
  rating: number,
  comment?: string | null,
): Promise<CsatDTO> {
  if (!Number.isInteger(rating) || rating < 1 || rating > 5) {
    throw badRequest('Rating must be an integer between 1 and 5');
  }
  const conv = await one(`SELECT agent_id FROM conversations WHERE id = $1`, [conversationId]);
  if (!conv) throw notFound('Conversation not found');

  // Upsert: a customer may change their mind before closing the widget.
  const row = await one(
    `INSERT INTO csat_ratings (conversation_id, agent_id, rating, comment)
     VALUES ($1,$2,$3,$4)
     ON CONFLICT (conversation_id)
     DO UPDATE SET rating = EXCLUDED.rating, comment = EXCLUDED.comment, created_at = now()
     RETURNING *`,
    [conversationId, conv.agent_id, rating, comment?.trim() || null],
  );
  return {
    conversationId: row.conversation_id,
    rating: row.rating,
    comment: row.comment ?? null,
    createdAt: new Date(row.created_at).toISOString(),
  };
}

export async function getCsat(conversationId: string): Promise<CsatDTO | null> {
  const row = await one(`SELECT * FROM csat_ratings WHERE conversation_id = $1`, [conversationId]);
  if (!row) return null;
  return {
    conversationId: row.conversation_id,
    rating: row.rating,
    comment: row.comment ?? null,
    createdAt: new Date(row.created_at).toISOString(),
  };
}

/** Rolling 30-day agent scorecard for the dashboard header. */
export async function agentCsatSummary(agentId: string) {
  const rows = await many(
    `SELECT AVG(rating)::numeric(3,2) AS avg_rating, COUNT(*) AS total
       FROM csat_ratings WHERE agent_id = $1 AND created_at > now() - interval '30 days'`,
    [agentId],
  );
  const r = rows[0] ?? {};
  return { averageRating: r.avg_rating ? Number(r.avg_rating) : null, total: Number(r.total ?? 0) };
}
