import { Body, Controller, Get, Param, Patch, Post, Query, Req, UseGuards, UsePipes, ValidationPipe } from '@nestjs/common';
import { ApiBearerAuth, ApiBody, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
import { AuthGuard } from 'src/auth/auth.guard';
import { RolesGuard } from 'src/guard/role.guard';
import { Roles } from 'src/guard/decorators/role.decorator';
import { CommonService } from 'src/common/common.service';
import { PANEL_ROLES, UserType } from 'src/user/schema/users.schema';
import { PolicyService } from './policy.service';
import { CancelPolicyDto, CreatePolicyDto, PolicyListDto, UpdatePolicyDto } from './dto/policy.dto';

@ApiTags('Policies')
@ApiBearerAuth('access_token')
@UseGuards(AuthGuard, RolesGuard)
@Roles(...PANEL_ROLES)
@UsePipes(new ValidationPipe({ transform: true, whitelist: true }))
@Controller('admin/policies')
export class PolicyController {
    constructor(
        private readonly policyService: PolicyService,
        private readonly common: CommonService
    ) { }

    @Post()
    @ApiOperation({ summary: 'Enter an offline policy. Net premium, GST and agent commission are calculated from the product.' })
    @ApiBody({ type: CreatePolicyDto })
    @ApiResponse({ status: 400, description: 'Duplicate policy number, bad dates, inactive product, or assignee not authorised for the product' })
    create(@Req() req: any, @Body() dto: CreatePolicyDto) {
        return this.policyService.create(dto, req.user_data, this.common.getUserLanguage(req));
    }

    @Get()
    @ApiOperation({ summary: 'List policies (filter by category_id, product_id, insurer_id, assigned_to, customer_id, status, issued, expiring_in_days, search). Policy Staff see only their own.' })
    list(@Req() req: any, @Query() query: PolicyListDto) {
        return this.policyService.list(query, req.user_data, this.common.getUserLanguage(req));
    }

    @Get(':id')
    @ApiOperation({ summary: 'Policy detail: customer, insured members, financials and the schedule file. Commission is hidden from Policy Staff.' })
    @ApiResponse({ status: 404, description: 'Policy not found (or not handled by you)' })
    getById(@Req() req: any, @Param('id') id: string) {
        return this.policyService.getById(id, req.user_data, this.common.getUserLanguage(req));
    }

    @Patch(':id')
    @ApiOperation({ summary: 'Correct a policy: premium (recalculated), frequency, dates, insured members, vehicle, sum insured, schedule file' })
    @ApiBody({ type: UpdatePolicyDto })
    update(@Req() req: any, @Param('id') id: string, @Body() dto: UpdatePolicyDto) {
        return this.policyService.update(id, dto, req.user_data, this.common.getUserLanguage(req));
    }

    @Post(':id/cancel')
    @Roles(UserType.SUPER_ADMIN, UserType.ADMIN_STAFF)
    @ApiOperation({ summary: 'Cancel a policy with a reason; pending commission is cancelled too' })
    @ApiBody({ type: CancelPolicyDto })
    cancel(@Req() req: any, @Param('id') id: string, @Body() dto: CancelPolicyDto) {
        return this.policyService.cancel(id, dto, req.user_data, this.common.getUserLanguage(req));
    }
}
