import { Body, Controller, Delete, Get, Param, Patch, Post, Put, Query } from "@nestjs/common";
import { CurrentUser } from "../../common/decorators/current-user.decorator";
import { Permissions } from "../../common/decorators/permissions.decorator";
import { AdminService } from "./admin.service";

type AdminActor = { sub: string };

@Controller("admin")
export class AdminController {
  constructor(private readonly admin: AdminService) {}

  @Get("users/:id") @Permissions("users.read")
  userDetail(@Param("id") id: string) { return this.admin.userDetail(id); }

  @Patch("users/:id") @Permissions("users.manage")
  updateUser(@Param("id") id: string, @Body() body: Record<string, unknown>, @CurrentUser() actor: AdminActor) { return this.admin.updateUser(id, body, actor.sub); }

  @Patch("users/:id/password") @Permissions("users.manage")
  resetUserPassword(@Param("id") id: string, @Body("password") password: unknown, @CurrentUser() actor: AdminActor) { return this.admin.resetUserPassword(id, password, actor.sub); }

  @Post("users/:id/ads") @Permissions("ads.moderate")
  createUserAd(@Param("id") id: string, @Body() body: Record<string, unknown>, @CurrentUser() actor: AdminActor) { return this.admin.saveUserAd(id, undefined, body, actor.sub); }

  @Patch("users/:id/ads/:adId") @Permissions("ads.moderate")
  updateUserAd(@Param("id") id: string, @Param("adId") adId: string, @Body() body: Record<string, unknown>, @CurrentUser() actor: AdminActor) { return this.admin.saveUserAd(id, adId, body, actor.sub); }

  @Delete("users/:id/ads/:adId") @Permissions("ads.moderate")
  deleteUserAd(@Param("id") id: string, @Param("adId") adId: string, @CurrentUser() actor: AdminActor) { return this.admin.deleteUserAd(id, adId, actor.sub); }

  @Get("conversations/:id") @Permissions("conversations.read_sensitive")
  conversationDetail(@Param("id") id: string, @CurrentUser() actor: AdminActor) { return this.admin.conversationDetail(id, actor.sub); }

  @Delete("categories/:id") @Permissions("settings.write")
  deleteCategory(@Param("id") id: string, @Body("replacementId") replacementId: string | undefined, @CurrentUser() actor: AdminActor) { return this.admin.deleteCategory(id, replacementId, actor.sub); }

  @Delete("services/:id") @Permissions("settings.write")
  deleteService(@Param("id") id: string, @CurrentUser() actor: AdminActor) { return this.admin.deleteService(id, actor.sub); }

  @Get("dashboard") @Permissions("users.read")
  dashboard() { return this.admin.dashboard(); }

  @Get("users") @Permissions("users.read")
  users(@Query("page") page?: string, @Query("limit") limit?: string, @Query("search") search?: string) {
    return this.admin.listUsers(Number(page ?? 1), Number(limit ?? 20), search);
  }

  @Patch("users/:id/activate") @Permissions("users.suspend")
  activate(@Param("id") id: string, @CurrentUser() actor: AdminActor) { return this.admin.setUserActive(id, true, actor.sub); }

  @Patch("users/:id/deactivate") @Permissions("users.suspend")
  deactivate(@Param("id") id: string, @CurrentUser() actor: AdminActor) { return this.admin.setUserActive(id, false, actor.sub); }

  @Patch("users/:id/access") @Permissions("admins.manage")
  access(@Param("id") id: string, @Body() body: { role?: string; permissions?: string[] }, @CurrentUser() actor: AdminActor) {
    return this.admin.setUserAccess(id, body, actor.sub);
  }

  @Get("providers") @Permissions("users.read")
  providers(@Query("page") page?: string, @Query("limit") limit?: string, @Query("search") search?: string, @Query("verified") verified?: string) {
    return this.admin.listProviders(Number(page ?? 1), Number(limit ?? 20), search, verified);
  }

  @Patch("providers/:id/verification") @Permissions("users.suspend")
  verification(@Param("id") id: string, @Body("verified") verified: boolean, @CurrentUser() actor: AdminActor) {
    return this.admin.setProviderVerification(id, verified, actor.sub);
  }

  @Get("categories") @Permissions("ads.read")
  categories() { return this.admin.listCategories(); }

  @Post("categories") @Permissions("settings.write")
  createCategory(@Body() body: Record<string, unknown>, @CurrentUser() actor: AdminActor) { return this.admin.createCategory(body, actor.sub); }

  @Patch("categories/:id") @Permissions("settings.write")
  updateCategory(@Param("id") id: string, @Body() body: Record<string, unknown>, @CurrentUser() actor: AdminActor) { return this.admin.updateCategory(id, body, actor.sub); }

  @Post("categories/:id/services") @Permissions("settings.write")
  createService(@Param("id") id: string, @Body() body: Record<string, unknown>, @CurrentUser() actor: AdminActor) { return this.admin.createService(id, body, actor.sub); }

  @Patch("services/:id") @Permissions("settings.write")
  updateService(@Param("id") id: string, @Body() body: Record<string, unknown>, @CurrentUser() actor: AdminActor) { return this.admin.updateService(id, body, actor.sub); }

  @Get("ads") @Permissions("ads.moderate")
  ads(@Query("page") page?: string, @Query("limit") limit?: string, @Query("status") status?: string) {
    return this.admin.listAds(Number(page ?? 1), Number(limit ?? 20), status);
  }

  @Patch("ads/:id/status") @Permissions("ads.moderate")
  adStatus(@Param("id") id: string, @Body("status") status: string, @CurrentUser() actor: AdminActor) {
    return this.admin.setAdStatus(id, status, actor.sub);
  }

  @Get("deleted-ads") @Permissions("ads.moderate")
  deletedAds(@Query("page") page?: string, @Query("limit") limit?: string, @Query("search") search?: string, @Query("period") period?: string) {
    return this.admin.listDeletedAds(Number(page ?? 1), Number(limit ?? 20), search, period);
  }

  @Patch("deleted-ads/:id/restore") @Permissions("ads.moderate")
  restoreDeletedAd(@Param("id") id: string, @CurrentUser() actor: AdminActor) {
    return this.admin.restoreDeletedAd(id, actor.sub);
  }

  @Get("requests") @Permissions("requests.read")
  requests(@Query("page") page?: string, @Query("limit") limit?: string, @Query("status") status?: string) {
    return this.admin.listRequests(Number(page ?? 1), Number(limit ?? 20), status);
  }

  @Patch("requests/:id/status") @Permissions("requests.manage")
  requestStatus(@Param("id") id: string, @Body("status") status: string, @CurrentUser() actor: AdminActor) {
    return this.admin.setRequestStatus(id, status, actor.sub);
  }

  @Get("offers") @Permissions("offers.read")
  offers(@Query("page") page?: string, @Query("limit") limit?: string, @Query("status") status?: string) {
    return this.admin.listOffers(Number(page ?? 1), Number(limit ?? 20), status);
  }

  @Patch("offers/:id/status") @Permissions("offers.manage")
  offerStatus(@Param("id") id: string, @Body("status") status: string, @CurrentUser() actor: AdminActor) {
    return this.admin.setOfferStatus(id, status, actor.sub);
  }

  @Get("conversations") @Permissions("conversations.read_sensitive")
  conversations(@Query("page") page?: string, @Query("limit") limit?: string) {
    return this.admin.listConversations(Number(page ?? 1), Number(limit ?? 20));
  }

  @Get("reports") @Permissions("reports.manage")
  reports(@Query("page") page?: string, @Query("limit") limit?: string, @Query("status") status?: string) {
    return this.admin.listReports(Number(page ?? 1), Number(limit ?? 20), status);
  }

  @Patch("reports/:id") @Permissions("reports.manage")
  reportStatus(@Param("id") id: string, @Body("status") status: string, @CurrentUser() actor: AdminActor) {
    return this.admin.setReportStatus(id, status, actor.sub);
  }

  @Get("reviews") @Permissions("users.read")
  reviews(@Query("page") page?: string, @Query("limit") limit?: string) { return this.admin.listReviews(Number(page ?? 1), Number(limit ?? 20)); }

  @Patch("reviews/:id/visibility") @Permissions("reports.manage")
  reviewVisibility(@Param("id") id: string, @Body("hidden") hidden: boolean, @CurrentUser() actor: AdminActor) {
    return this.admin.setReviewVisibility(id, hidden, actor.sub);
  }

  @Get("notifications") @Permissions("notifications.send")
  notifications(@Query("page") page?: string, @Query("limit") limit?: string) { return this.admin.listNotifications(Number(page ?? 1), Number(limit ?? 20)); }

  @Post("notifications/broadcast") @Permissions("notifications.send")
  broadcast(@Body() body: { title?: string; body?: string; type?: string }, @CurrentUser() actor: AdminActor) {
    return this.admin.broadcastNotification(body, actor.sub);
  }

  @Get("locations") @Permissions("users.read")
  locations() { return this.admin.listLocations(); }

  @Get("settings") @Permissions("settings.write")
  settings() { return this.admin.getSettings(); }

  @Put("settings") @Permissions("settings.write")
  saveSettings(@Body() body: Record<string, unknown>, @CurrentUser() actor: AdminActor) { return this.admin.saveSettings(body, actor.sub); }

  @Get("roles") @Permissions("admins.manage")
  roles() { return this.admin.listAdminUsers(); }

  @Get("audit") @Permissions("audit.read")
  audit(@Query("page") page?: string, @Query("limit") limit?: string) { return this.admin.listAudit(Number(page ?? 1), Number(limit ?? 30)); }
}
