import { Request, Response, NextFunction, RequestHandler } from "express";
import { Query } from "../models/Queries";

export class QueryController {
  private sendError(res: Response, status: number, message: string): void {
    res.status(status).json({ message });
  }

  private sendSuccess(res: Response, message: string, data?: any): void {
    res.status(200).json({ success: true, message, data });
  }
  show: RequestHandler = async (
    req: Request,
    res: Response,
    next: NextFunction
  ): Promise<void> => {
    try {
      const queries = await Query.query().select(
        "id",
        "query_name",
        "total_token",
        "total_characters"
      );
      this.sendSuccess(res, "Queries fetched successfully", queries);
    } catch (err) {
      console.error("Error fetching custom pages:", err);
      next(err);
    }
  };

  add: RequestHandler = async (
    req: Request,
    res: Response,
    next: NextFunction
  ): Promise<void> => {
    try {
      const queryData = req.body;

      const existingQueryName = await Query.query()
        .whereRaw("query_name = ?", [queryData.query_name.toLowerCase()])
        .first();

      if (existingQueryName) {
        res.status(400).json({ message: "Query Name already exists" });
        return;
      }

      const newQuery = await Query.query().insert({
        query_name: queryData.query_name,
        total_token: queryData.total_token,
        total_characters: queryData.total_characters,
      });

      res
        .status(201)
        .json({ message: "User created successfully", query: newQuery });
    } catch (err: any) {
      console.error(err);
      res.status(500).json({ message: "Internal server error" });
    }
  };

  get: RequestHandler = async (
    req: Request,
    res: Response,
    next: NextFunction
  ): Promise<void> => {
    try {
      const queryID = req.params.id;

      if (!queryID) {
        res.status(400).json({ message: "Query ID is required" });
        return;
      }

      const query = await Query.query().findById(queryID);

      if (!query) {
        res.status(404).json({ message: "Query not found" });
        return;
      }

      res.status(200).json({
        success: true,
        message: "Query fetched successfully",
        data: query,
      });
    } catch (error) {
      console.error("Error fetching user:", error);
      res.status(500).json({ message: "Failed to fetch user" });
    }
  };

  edit: RequestHandler = async (
    req: Request,
    res: Response,
    next: NextFunction
  ): Promise<void> => {
    try {
      const { id } = req.params; // assume query id comes from route params
      const queryData = req.body;

      // Check if record exists
      const existingQuery = await Query.query().findById(id);
      if (!existingQuery) {
        res.status(404).json({ message: "Query not found" });
        return;
      }

      // Check if query_name already exists (for a different ID)
      if (queryData.query_name) {
        const duplicate = await Query.query()
          .whereRaw("LOWER(query_name) = ?", [
            queryData.query_name.toLowerCase(),
          ])
          .whereNot("id", id)
          .first();

        if (duplicate) {
          res.status(400).json({ message: "Query name already exists" });
          return;
        }
      }

      // Update the record
      const updatedQuery = await Query.query().patchAndFetchById(id, {
        query_name: queryData.query_name,
        total_token: queryData.total_token,
        total_characters: queryData.total_characters,
      });

      res.status(200).json({
        message: "Query updated successfully",
        query: updatedQuery,
      });
    } catch (err: any) {
      console.error(err);
      res.status(500).json({ message: "Internal server error" });
    }
  };

  delete: RequestHandler = async (
    req: Request,
    res: Response,
    next: NextFunction
  ): Promise<void> => {
    try {
      const { id } = req.params;

      if (!id) {
        this.sendError(res, 400, "Missing query ID");
        return;
      }

      const query = await Query.query().findById(id);
      if (!query) {
        this.sendError(res, 404, "Query not found");
        return;
      }

      await Query.query().deleteById(id);

      this.sendSuccess(res, "Query deleted successfully");
    } catch (error) {
      console.error("Error deleting query:", error);
      this.sendError(res, 500, "Failed to delete query");
    }
  };
}
