import {
  Body,
  Controller,
  Delete,
  Get,
  Param,
  ParseUUIDPipe,
  Post,
  Query,
  UseGuards,
} from '@nestjs/common';
import { JwtAuthGuard } from '../../auth/guards/jwt-auth.guard';
import { PermissionGuard } from '../../auth/guards/permission.guard';
import { Permissions } from '../../auth/decorators/permissions.decorator';
import { AccessLevel, ModuleName } from '../../entities/role-permission.entity';
import { successResponse } from '../../common/responses/api-response';
import { TaxSlabService } from './tax-slab.service';
import { UpsertTaxSlabDto, UpsertTaxTypeComponentsDto } from './dto/tax-slab.dto';

/**
 * Tax configuration endpoints, gated by SETTINGS.
 *
 *   Structure (component list under a TaxType):
 *     GET    /tax-types/:id/components           — list components
 *     POST   /tax-types/:id/components           — replace/upsert components
 *
 *   Per-destination slabs (rate assignment):
 *     GET    /tax-slabs?tax_type_id              — list slabs for a type
 *     GET    /tax-slabs?destination_id           — list slabs for a destination
 *     GET    /tax-slabs/for-destination?...      — resolve one
 *     POST   /tax-slabs                          — upsert (create/update)
 *     DELETE /tax-slabs/:id                      — soft delete
 */
@Controller()
@UseGuards(JwtAuthGuard, PermissionGuard)
export class TaxSlabController {
  constructor(private readonly service: TaxSlabService) {}

  // ── Components ────────────────────────────────────────────────

  @Get('tax-types/:id/components')
  @Permissions({ module: ModuleName.TAX_TYPE, accessLevel: AccessLevel.VIEW })
  async listComponents(@Param('id', ParseUUIDPipe) id: string) {
    const data = await this.service.listComponentsFor(id);
    return successResponse(data, 'Tax components fetched');
  }

  @Post('tax-types/:id/components')
  @Permissions({ module: ModuleName.TAX_TYPE, accessLevel: AccessLevel.EDIT })
  async upsertComponents(
    @Param('id', ParseUUIDPipe) id: string,
    @Body() dto: UpsertTaxTypeComponentsDto,
  ) {
    const r = await this.service.upsertComponents(id, dto.components);
    return successResponse(r, `${r.applied} components applied`);
  }

  // ── Slabs ─────────────────────────────────────────────────────

  @Get('tax-slabs')
  @Permissions({ module: ModuleName.TAX_TYPE, accessLevel: AccessLevel.VIEW })
  async list(
    @Query('tax_type_id') tax_type_id?: string,
    @Query('destination_id') destination_id?: string,
  ) {
    if (destination_id) {
      const data = await this.service.listForDestination(destination_id);
      return successResponse(data, 'Slabs for destination fetched');
    }
    if (tax_type_id) {
      const data = await this.service.listForTaxType(tax_type_id);
      return successResponse(data, 'Slabs for tax type fetched');
    }
    return successResponse([], 'No filter provided');
  }

  @Get('tax-slabs/for-destination')
  @Permissions({ module: ModuleName.TAX_TYPE, accessLevel: AccessLevel.VIEW })
  async lookup(
    @Query('tax_type_id', ParseUUIDPipe) tax_type_id: string,
    @Query('destination_id', ParseUUIDPipe) destination_id: string,
  ) {
    const data = await this.service.findForDestination(tax_type_id, destination_id);
    return successResponse(data, data ? 'Slab matched' : 'No slab configured');
  }

  @Post('tax-slabs')
  @Permissions({ module: ModuleName.TAX_TYPE, accessLevel: AccessLevel.EDIT })
  async upsert(@Body() dto: UpsertTaxSlabDto) {
    const r = await this.service.upsertSlab(dto);
    return successResponse(r, r.created ? 'Tax slab created' : 'Tax slab updated');
  }

  @Delete('tax-slabs/:id')
  @Permissions({ module: ModuleName.TAX_TYPE, accessLevel: AccessLevel.DELETE })
  async remove(@Param('id', ParseUUIDPipe) id: string) {
    const r = await this.service.removeSlab(id);
    return successResponse(r, r.message);
  }
}
