import type { Response } from "express";
import type { AuthenticatedRequest } from "../@types/auth.js";
import type {
  AdminOrderListQueryInput,
  CreateOrderInput,
  CustomerOrderListQueryInput,
  OrderIdParamInput,
  UpdateOrderInput,
} from "../@types/orderRequests.js";
import {
  createCustomerOrder,
  getAdminOrderById,
  getCustomerOrderById,
  getDashboardSummary,
  listAdminOrders,
  listCustomerOrders,
  updateAdminOrder,
} from "../services/orderService.js";
import { sendError, sendSuccess } from "../utils/apiResponse.js";

const getCustomerId = (req: AuthenticatedRequest) => {
  if (req.auth?.actorType !== "customer") return null;
  return req.auth.customer.id;
};

const getStaffId = (req: AuthenticatedRequest) => {
  if (req.auth?.actorType !== "staff") return null;
  return req.auth.staff.id;
};

export const createOrder = async (req: AuthenticatedRequest, res: Response) => {
  const customerId = getCustomerId(req);
  if (!customerId)
    return sendError(res, 403, "FORBIDDEN", "Customer access required.");

  try {
    const order = await createCustomerOrder(
      customerId,
      req.validatedBody as CreateOrderInput,
    );
    return sendSuccess(res, 201, order, "Order placed successfully.");
  } catch (error) {
    const message =
      error instanceof Error ? error.message : "Could not place order.";
    return sendError(res, 400, "ORDER_CREATE_FAILED", message);
  }
};

export const listMyOrders = async (
  req: AuthenticatedRequest,
  res: Response,
) => {
  const customerId = getCustomerId(req);
  if (!customerId)
    return sendError(res, 403, "FORBIDDEN", "Customer access required.");

  const result = await listCustomerOrders(
    customerId,
    req.validatedQuery as CustomerOrderListQueryInput,
  );
  return sendSuccess(res, 200, result);
};

export const getMyOrderById = async (
  req: AuthenticatedRequest,
  res: Response,
) => {
  const customerId = getCustomerId(req);
  if (!customerId)
    return sendError(res, 403, "FORBIDDEN", "Customer access required.");

  const { id } = req.validatedParams as OrderIdParamInput;
  const order = await getCustomerOrderById(customerId, id);
  if (!order) return sendError(res, 404, "ORDER_NOT_FOUND", "Order not found.");

  return sendSuccess(res, 200, order);
};

export const listOrdersForAdmin = async (
  req: AuthenticatedRequest,
  res: Response,
) => {
  const result = await listAdminOrders(
    req.validatedQuery as AdminOrderListQueryInput,
  );
  return sendSuccess(res, 200, result);
};

export const getOrderForAdmin = async (
  req: AuthenticatedRequest,
  res: Response,
) => {
  const { id } = req.validatedParams as OrderIdParamInput;
  const order = await getAdminOrderById(id);
  if (!order) return sendError(res, 404, "ORDER_NOT_FOUND", "Order not found.");

  return sendSuccess(res, 200, order);
};

export const updateOrderForAdmin = async (
  req: AuthenticatedRequest,
  res: Response,
) => {
  const staffId = getStaffId(req);
  if (!staffId)
    return sendError(res, 403, "FORBIDDEN", "Staff access required.");

  const { id } = req.validatedParams as OrderIdParamInput;
  const order = await updateAdminOrder(
    id,
    req.validatedBody as UpdateOrderInput,
    staffId,
  );
  if (!order) return sendError(res, 404, "ORDER_NOT_FOUND", "Order not found.");

  return sendSuccess(res, 200, order, "Order updated.");
};

export const getAdminDashboard = async (
  _req: AuthenticatedRequest,
  res: Response,
) => {
  const result = await getDashboardSummary();
  return sendSuccess(res, 200, result);
};
