import { Response } from "express";
import { Types } from "mongoose";
import GasStationModel from "../../models/GasStationModel";
import ResponseUtil from "../../utils/Response/responseUtils";
import { STATUS_CODES } from "../../constants/statusCodes";
import { CustomRequest } from "../../interfaces/auth";
import { adminApprovalBodySchema } from "../../validators/adminValidators";

export const listPendingGasStations = async (
  req: CustomRequest,
  res: Response
) => {
  try {
    const page = Math.max(parseInt((req.query.page as string) || "1", 10), 1);
    const limit = Math.min(
      Math.max(parseInt((req.query.limit as string) || "20", 10), 1),
      100
    );
    const skip = (page - 1) * limit;

    const filter = { approvalStatus: "pending" as const, isActive: true };
    const [stations, total] = await Promise.all([
      GasStationModel.find(filter)
        .sort({ createdAt: -1 })
        .skip(skip)
        .limit(limit)
        .populate("userId", "email fullName phone")
        .lean(),
      GasStationModel.countDocuments(filter),
    ]);

    return ResponseUtil.successResponse(
      res,
      STATUS_CODES.SUCCESS,
      { total, page, limit, totalPages: Math.ceil(total / limit), stations },
      "Pending gas stations"
    );
  } catch (e) {
    ResponseUtil.handleError(res, e);
  }
};

export const listAllGasStationsAdmin = async (
  req: CustomRequest,
  res: Response
) => {
  try {
    const page = Math.max(parseInt((req.query.page as string) || "1", 10), 1);
    const limit = Math.min(
      Math.max(parseInt((req.query.limit as string) || "20", 10), 1),
      100
    );
    const skip = (page - 1) * limit;
    const status = req.query.approvalStatus as string | undefined;
    const filter: Record<string, unknown> = {};
    if (status && ["pending", "approved", "rejected"].includes(status)) {
      filter.approvalStatus = status;
    }

    const [stations, total] = await Promise.all([
      GasStationModel.find(filter)
        .sort({ createdAt: -1 })
        .skip(skip)
        .limit(limit)
        .populate("userId", "email fullName phone")
        .lean(),
      GasStationModel.countDocuments(filter),
    ]);

    return ResponseUtil.successResponse(
      res,
      STATUS_CODES.SUCCESS,
      { total, page, limit, totalPages: Math.ceil(total / limit), stations },
      "Gas stations"
    );
  } catch (e) {
    ResponseUtil.handleError(res, e);
  }
};

export const approveGasStation = async (req: CustomRequest, res: Response) => {
  try {
    const { id } = req.params;
    const body = await adminApprovalBodySchema.parseAsync(req.body);
    if (!Types.ObjectId.isValid(id)) {
      return ResponseUtil.errorResponse(
        res,
        STATUS_CODES.BAD_REQUEST,
        "Invalid id"
      );
    }

    const station = await GasStationModel.findByIdAndUpdate(
      id,
      {
        approvalStatus: "approved",
        approvalNote: body.note ?? "",
        approvedAt: new Date(),
        approvedBy: new Types.ObjectId(req.userId),
        isActive: true,
      },
      { new: true }
    ).lean();

    if (!station) {
      return ResponseUtil.errorResponse(
        res,
        STATUS_CODES.NOT_FOUND,
        "Gas station not found"
      );
    }

    return ResponseUtil.successResponse(
      res,
      STATUS_CODES.SUCCESS,
      { station },
      "Gas station approved"
    );
  } catch (e) {
    ResponseUtil.handleError(res, e);
  }
};

export const rejectGasStation = async (req: CustomRequest, res: Response) => {
  try {
    const { id } = req.params;
    const body = await adminApprovalBodySchema.parseAsync(req.body);
    if (!Types.ObjectId.isValid(id)) {
      return ResponseUtil.errorResponse(
        res,
        STATUS_CODES.BAD_REQUEST,
        "Invalid id"
      );
    }

    const station = await GasStationModel.findByIdAndUpdate(
      id,
      {
        approvalStatus: "rejected",
        approvalNote: body.note ?? "",
        approvedAt: new Date(),
        approvedBy: new Types.ObjectId(req.userId),
        isActive: false,
      },
      { new: true }
    ).lean();

    if (!station) {
      return ResponseUtil.errorResponse(
        res,
        STATUS_CODES.NOT_FOUND,
        "Gas station not found"
      );
    }

    return ResponseUtil.successResponse(
      res,
      STATUS_CODES.SUCCESS,
      { station },
      "Gas station rejected"
    );
  } catch (e) {
    ResponseUtil.handleError(res, e);
  }
};

export const getGasStationAdmin = async (req: CustomRequest, res: Response) => {
  try {
    const { id } = req.params;
    if (!Types.ObjectId.isValid(id)) {
      return ResponseUtil.errorResponse(
        res,
        STATUS_CODES.BAD_REQUEST,
        "Invalid id"
      );
    }
    const station = await GasStationModel.findById(id)
      .populate("userId", "email fullName phone")
      .lean();
    if (!station) {
      return ResponseUtil.errorResponse(
        res,
        STATUS_CODES.NOT_FOUND,
        "Gas station not found"
      );
    }
    return ResponseUtil.successResponse(
      res,
      STATUS_CODES.SUCCESS,
      { station },
      "Gas station detail"
    );
  } catch (e) {
    ResponseUtil.handleError(res, e);
  }
};
