import {
  Controller,
  Post,
  Body,
  Get,
  Param,
  Put,
  HttpException,
  HttpStatus,
  Query,
} from '@nestjs/common';
import { TempFranchiseService } from './temp_franchise.service';
import { Public } from '../auth/public.decorator';
import {
  ApiBearerAuth,
  ApiTags,
  ApiBody,
  ApiParam,
  ApiQuery,
  ApiOperation,
} from '@nestjs/swagger';

@ApiTags('tempFranchise')
@ApiBearerAuth('access-token')
@Controller('tempFranchise')
export class TempFranchiseController {
  constructor(private readonly tempFranchiseService: TempFranchiseService) {}

  @Public()
  @Post('apply')
  @ApiOperation({
    summary: 'Submit Franchise Application',
    description:
      'Public endpoint for users to apply for a franchise. Data is saved for admin review. Status will be "applied".',
  })
  @ApiBody({
    schema: {
      type: 'object',
      properties: {
        full_name: { type: 'string' },
        email: { type: 'string', format: 'email' },
        phone: { type: 'string' },
        company_name: { type: 'string' },
        address: { type: 'string' },
        country_id: { type: 'number' },
        state_id: { type: 'number' },
        city_id: { type: 'number' },
        postal_code: { type: 'string' },
        area_id: { type: 'number' },
        business_experience: { type: 'string' },
        investment_range: { type: 'string' },
        preferred_location: { type: 'string' },
        motivation: { type: 'string' },
        additional_info: { type: 'string' },
        gst_number: { type: 'string' },
      },
      required: [
        'full_name',
        'email',
        'phone',
        'address',
        'business_experience',
        'investment_range',
        'preferred_location',
        'motivation',
        'country_id',
        'state_id',
        'city_id',
      ],
    },
  })
  async submitApplication(@Body() applicationData: any) {
    try {
      const result =
        await this.tempFranchiseService.submitApplication(applicationData);
      return {
        success: true,
        message: 'Franchise application submitted successfully',
        data: result,
      };
    } catch (error) {
      throw new HttpException(
        { message: error.message || 'Error submitting application' },
        HttpStatus.INTERNAL_SERVER_ERROR,
      );
    }
  }

  @Public()
  @Get('applications')
  @ApiOperation({ summary: 'Get Franchise Applications' })
  @ApiQuery({ name: 'status', required: false, type: String })
  @ApiQuery({ name: 'page', required: false, type: String })
  @ApiQuery({ name: 'limit', required: false, type: String })
  async getApplications(
    @Query('status') status?: string,
    @Query('page') page?: string,
    @Query('limit') limit?: string,
  ) {
    try {
      const pageNumber = page ? parseInt(page) : 1;
      const limitNumber = limit ? parseInt(limit) : 10;

      const result = await this.tempFranchiseService.getApplications(
        status,
        pageNumber,
        limitNumber,
      );

      return {
        success: true,
        data: {
          applications: result.applications,
          pagination: {
            total: result.total,
            totalPages: result.totalPages,
            currentPage: pageNumber,
            limit: limitNumber,
          },
        },
      };
    } catch (error) {
      throw new HttpException(
        { message: error.message || 'Error fetching applications' },
        HttpStatus.INTERNAL_SERVER_ERROR,
      );
    }
  }

  @Public()
  @Get(':id')
  @ApiOperation({ summary: 'Get Franchise Application by ID' })
  @ApiParam({ name: 'id', type: Number })
  async getApplicationById(@Param('id') id: number) {
    try {
      const application =
        await this.tempFranchiseService.getApplicationById(id);
      return {
        success: true,
        data: application,
      };
    } catch (error) {
      throw new HttpException(
        { message: error.message || 'Error fetching application' },
        HttpStatus.INTERNAL_SERVER_ERROR,
      );
    }
  }

  @Public()
  @Put(':id/approve')
  @ApiOperation({
    summary: 'Approve Franchise Application',
    description:
      'Admin only. Approves the application and AUTOMATICALLY CREATES A USER ACCOUNT for the franchise owner, enabling them to login via OTP.',
  })
  @ApiParam({ name: 'id', type: Number })
  @ApiBody({
    schema: {
      type: 'object',
      properties: {
        adminId: { type: 'number', example: 1 },
        remarks: { type: 'string', example: 'Approved' },
      },
      required: ['adminId'],
    },
  })
  async approveApplication(
    @Param('id') id: number,
    @Body() approvalData: { adminId: number; remarks?: string },
  ) {
    try {
      const result = await this.tempFranchiseService.approveApplication(
        id,
        approvalData.adminId,
        approvalData.remarks,
      );
      return {
        success: true,
        message: 'Application approved successfully',
        data: result,
      };
    } catch (error) {
      throw new HttpException(
        { message: error.message || 'Error approving application' },
        HttpStatus.INTERNAL_SERVER_ERROR,
      );
    }
  }

  @Public()
  @Put(':id/reject')
  @ApiOperation({ summary: 'Reject Franchise Application' })
  @ApiParam({ name: 'id', type: Number })
  @ApiBody({
    schema: {
      type: 'object',
      properties: {
        adminId: { type: 'number', example: 1 },
        remarks: { type: 'string', example: 'Rejected' },
      },
      required: ['adminId'],
    },
  })
  async rejectApplication(
    @Param('id') id: number,
    @Body() rejectionData: { adminId: number; remarks?: string },
  ) {
    try {
      const result = await this.tempFranchiseService.rejectApplication(
        id,
        rejectionData.adminId,
        rejectionData.remarks,
      );
      return {
        success: true,
        message: 'Application rejected successfully',
        data: result,
      };
    } catch (error) {
      throw new HttpException(
        { message: error.message || 'Error rejecting application' },
        HttpStatus.INTERNAL_SERVER_ERROR,
      );
    }
  }
}
