import { v4 as uuidv4 } from 'uuid';
import { db } from '../application/database';
import { ResponseError } from '../error/response-error';
import { FaqResponse, toFaqResponse, CreateFaqRequest, UpdateFaqRequest, Faq } from '../model/faq-model';
import { FaqValidation } from '../validation/faq-validation';
import { Validation } from '../validation/validation';

export class FaqService {
  static async create(request: CreateFaqRequest): Promise<FaqResponse> {
    // Validate the create request
    const createRequest = Validation.validate(FaqValidation.CREATE, request);

    // Generate a UUID for the new faq
    const faqId = uuidv4();

    // Insert the new faq into the database with the UUID
    await db.query('INSERT INTO faq (id, question, answer) VALUES (?, ?, ?)', [
      faqId,
      createRequest.question,
      createRequest.answer,
    ]);

    // Retrieve the newly created faq by the UUID
    const faq = await db.queryOne<Faq>('SELECT * FROM faq WHERE id = ? LIMIT 1', [faqId]);

    if (!faq) {
      throw new ResponseError(500, 'Failed to create faq');
    }

    return toFaqResponse(faq);
  }

  static async getAll(): Promise<FaqResponse[]> {
    // Retrieve all faqs from the database
    const faqs = await db.query<Faq>('SELECT * FROM faq ORDER BY created_at ASC');

    // Map each faq to the response format
    return faqs.map(toFaqResponse);
  }

  static async get(id: string): Promise<FaqResponse> {
    // Retrieve a single faq by ID
    const faq = await db.queryOne<Faq>('SELECT * FROM faq WHERE id = ? LIMIT 1', [id]);

    if (!faq) {
      throw new ResponseError(404, 'Faq not found');
    }

    return toFaqResponse(faq);
  }

  static async update(id: string, request: UpdateFaqRequest): Promise<FaqResponse> {
    // Check if the faq exists
    const existingFaq = await db.queryOne<{ id: string }>('SELECT id FROM faq WHERE id = ? LIMIT 1', [id]);

    if (!existingFaq) {
      throw new ResponseError(404, 'Faq not found');
    }

    // Validate the update request
    const updateRequest = Validation.validate(FaqValidation.UPDATE, request);

    // Update the faq in the database
    await db.query('UPDATE faq SET question = ?, answer = ? WHERE id = ?', [updateRequest.question, updateRequest.answer, id]);

    // Retrieve the updated faq by the ID
    const faq = await db.queryOne<Faq>('SELECT * FROM faq WHERE id = ? LIMIT 1', [id]);

    if (!faq) {
      throw new ResponseError(500, 'Failed to update faq');
    }

    return toFaqResponse(faq);
  }

  static async delete(id: string): Promise<void> {
    // Check if the faq exists
    const existingFaq = await db.queryOne<{ id: string }>('SELECT id FROM faq WHERE id = ? LIMIT 1', [id]);

    if (!existingFaq) {
      throw new ResponseError(404, 'Faq not found');
    }

    // Delete the faq from the database
    await db.query('DELETE FROM faq WHERE id = ?', [id]);
  }

}