import { Body, Controller, Get, Param, Post, Query } from '@nestjs/common';
import { ApiBody, ApiOperation, ApiParam, ApiQuery, ApiResponse, ApiTags } from '@nestjs/swagger';
import { Public } from '../auth/public.decorator';
import { ApiValidationError, ESTATE_ID_EXAMPLE } from '../common/swagger-docs';
import {
  EstateAdminLeadSignupDto,
  InitializeEstatePaymentDto,
  RecordEstatePaymentDto,
  SelectSubscriptionPlanDto
} from './dto/onboarding.dto';
import { OnboardingService } from './onboarding.service';

@Public()
@ApiTags('Onboarding')
@Controller({ path: 'onboarding', version: '1' })
export class OnboardingController {
  constructor(private readonly onboardingService: OnboardingService) {}

  @Get('subscription-plans')
  @ApiOperation({
    summary: 'List public subscription plans',
    description:
      'Returns active estate subscription plans. Unit counts refer to residents/units/houses: Starter 0-100, Secure 101-500, Luxury 501-2000, Business 2001-5000. Enterprise remains a future/non-public custom plan.'
  })
  @ApiResponse({
    status: 200,
    description: 'Subscription plans returned.',
    schema: {
      example: [
        {
          code: 'STARTER',
          name: 'GateWise Starter',
          minResidents: 0,
          maxResidents: 100,
          monthlyPriceKobo: 20000000,
          currency: 'NGN',
          customPricing: false
        },
        {
          code: 'SECURE',
          name: 'GateWise Secure',
          minResidents: 101,
          maxResidents: 500,
          monthlyPriceKobo: 50000000,
          currency: 'NGN',
          customPricing: false
        },
        {
          code: 'LUXURY',
          name: 'GateWise Luxury',
          minResidents: 501,
          maxResidents: 2000,
          monthlyPriceKobo: 200000000,
          currency: 'NGN',
          customPricing: false
        },
        {
          code: 'BUSINESS',
          name: 'GateWise Business',
          minResidents: 2001,
          maxResidents: 5000,
          monthlyPriceKobo: 500000000,
          currency: 'NGN',
          customPricing: false
        }
      ]
    }
  })
  listSubscriptionPlans() {
    return this.onboardingService.listSubscriptionPlans();
  }

  @Get('payment-providers')
  @ApiOperation({
    summary: 'List enabled payment providers',
    description:
      'Returns global payment provider settings and, when estateId is supplied, the effective estate-specific setting after overrides.'
  })
  @ApiQuery({ name: 'estateId', required: false, example: ESTATE_ID_EXAMPLE })
  @ApiResponse({
    status: 200,
    description: 'Payment provider settings returned.',
    schema: {
      example: [
        {
          provider: 'FLUTTERWAVE',
          displayName: 'Flutterwave',
          globallyEnabled: true,
          estateEnabled: null,
          effectiveEnabled: true,
          recommendedUseCases: ['Nigeria payments', 'International/diaspora payments', 'Luxury estates']
        }
      ]
    }
  })
  listPaymentProviders(@Query('estateId') estateId?: string) {
    return this.onboardingService.listPaymentProviders(estateId);
  }

  @Post('estate-admin-signup')
  @ApiOperation({
    summary: 'Submit estate admin signup lead',
    description:
      'Allows a prospective estate admin to register interest. This creates a PENDING estate and a suspended ESTATE_ADMIN account pending GateWise review, payment, and activation.'
  })
  @ApiBody({ type: EstateAdminLeadSignupDto })
  @ApiResponse({
    status: 201,
    description: 'Estate admin signup submitted.',
    schema: {
      example: {
        estate: {
          id: ESTATE_ID_EXAMPLE,
          name: 'GreenPark Estate',
          location: 'Lagos, Nigeria',
          unitCount: 120,
          estateType: 'Residential gated community',
          status: 'PENDING',
          signupStatus: 'PENDING_APPROVAL'
        },
        admin: {
          id: 'user-uuid',
          name: 'Ade Okafor',
          phone: '+2348000000990',
          email: 'estate.admin@example.com',
          role: 'ESTATE_ADMIN',
          status: 'SUSPENDED'
        },
        nextStep: 'GateWise review is required before plan selection and activation.'
      }
    }
  })
  @ApiValidationError()
  submitEstateAdminLead(@Body() dto: EstateAdminLeadSignupDto) {
    return this.onboardingService.submitEstateAdminLead(dto);
  }

  @Post('estates/:estateId/select-plan')
  @ApiOperation({
    summary: 'Select subscription plan and payment provider',
    description:
      'Used after GateWise approval. The estate admin identifies themselves by signup phone, then selects a plan and enabled payment provider.'
  })
  @ApiParam({ name: 'estateId', example: ESTATE_ID_EXAMPLE })
  @ApiBody({ type: SelectSubscriptionPlanDto })
  @ApiResponse({
    status: 201,
    description: 'Plan selected.',
    schema: {
      example: {
        estate: {
          id: ESTATE_ID_EXAMPLE,
          subscriptionStatus: 'PLAN_SELECTED',
          selectedPaymentProvider: 'FLUTTERWAVE',
          subscriptionPlan: { code: 'SECURE', name: 'GateWise Secure' }
        },
        nextStep: 'Initialize a hosted payment checkout, then return for payment confirmation.'
      }
    }
  })
  @ApiValidationError()
  selectSubscriptionPlan(@Param('estateId') estateId: string, @Body() dto: SelectSubscriptionPlanDto) {
    return this.onboardingService.selectSubscriptionPlan(estateId, dto);
  }

  @Post('estates/:estateId/payments/initialize')
  @ApiOperation({
    summary: 'Initialize hosted payment',
    description:
      'Creates a pending estate subscription payment and initializes a hosted checkout session with the selected payment provider. Open the returned checkoutUrl to complete payment.'
  })
  @ApiParam({ name: 'estateId', example: ESTATE_ID_EXAMPLE })
  @ApiBody({ type: InitializeEstatePaymentDto })
  @ApiResponse({
    status: 201,
    description: 'Sandbox checkout initialized.',
    schema: {
      example: {
        payment: {
          id: 'payment-uuid',
          estateId: ESTATE_ID_EXAMPLE,
          provider: 'FLUTTERWAVE',
          reference: 'FLU-1778881112222-a1b2c3d4',
          status: 'PENDING'
        },
        checkout: {
          provider: 'FLUTTERWAVE',
          mode: 'sandbox',
          reference: 'FLU-1778881112222-a1b2c3d4',
          providerReference: 'FLU-1778881112222-a1b2c3d4',
          checkoutUrl: 'https://checkout.flutterwave.com/v3/hosted/pay/example',
          accessCode: null
        },
        nextStep: 'Open checkoutUrl, complete payment, then wait for GateWise confirmation.'
      }
    }
  })
  @ApiValidationError()
  initializePayment(@Param('estateId') estateId: string, @Body() dto: InitializeEstatePaymentDto) {
    return this.onboardingService.initializePayment(estateId, dto);
  }

  @Post('estates/:estateId/payments')
  @ApiOperation({
    summary: 'Record manual payment reference',
    description:
      'Records a pending manual/offline payment reference after transfer or non-hosted checkout. Hosted sandbox checkout should use /payments/initialize.'
  })
  @ApiParam({ name: 'estateId', example: ESTATE_ID_EXAMPLE })
  @ApiBody({ type: RecordEstatePaymentDto })
  @ApiResponse({
    status: 201,
    description: 'Payment reference recorded.',
    schema: {
      example: {
        payment: {
          id: 'payment-uuid',
          estateId: ESTATE_ID_EXAMPLE,
          provider: 'FLUTTERWAVE',
          reference: 'FLW-TEST-REFERENCE-001',
          status: 'PENDING'
        },
        nextStep: 'GateWise must confirm the payment before the estate becomes active.'
      }
    }
  })
  @ApiValidationError()
  recordPayment(@Param('estateId') estateId: string, @Body() dto: RecordEstatePaymentDto) {
    return this.onboardingService.recordPayment(estateId, dto);
  }

  @Get('payments/callback')
  @ApiOperation({
    summary: 'Receive hosted payment redirect callback',
    description:
      'Stores the gateway redirect query parameters after hosted checkout. This does not activate the estate by itself; GateWise payment confirmation still verifies the gateway and activates the estate.'
  })
  @ApiQuery({ name: 'provider', required: false, example: 'FLUTTERWAVE' })
  @ApiQuery({ name: 'reference', required: false, example: 'FLU-1778881112222-a1b2c3d4' })
  @ApiQuery({ name: 'tx_ref', required: false, example: 'FLU-1778881112222-a1b2c3d4' })
  @ApiQuery({ name: 'transaction_id', required: false, example: '123456789' })
  @ApiResponse({
    status: 200,
    description: 'Payment callback stored.',
    schema: {
      example: {
        status: 'received',
        payment: {
          id: 'payment-uuid',
          estateId: ESTATE_ID_EXAMPLE,
          provider: 'FLUTTERWAVE',
          reference: 'FLU-1778881112222-a1b2c3d4',
          status: 'PENDING'
        },
        nextStep: 'Payment callback stored. GateWise should confirm the payment to activate the estate.'
      }
    }
  })
  handlePaymentCallback(@Query() query: Record<string, unknown>) {
    return this.onboardingService.handlePaymentCallback(query);
  }
}
