import {
  Controller,
  Get,
  Post,
  Body,
  Patch,
  Param,
  Delete,
  Query,
  ParseIntPipe,
} from '@nestjs/common';
import { NewBillingService } from './new-billing.service';
import { CreateNewBillingDto } from './dto/create-new-billing.dto';
import { UpdateNewBillingDto } from './dto/update-new-billing.dto';
import { ApiOperation, ApiResponse } from '@nestjs/swagger';
import { ErrorResponse500 } from 'src/op-hub-appointment-status/op-hub-appointment-status.controller';
import { ErrorResponse400 } from 'src/op-hub-appointment/entities/op-hub-appointment.entity';
import { makepaymentV3 } from './entities/new-billing.entity';

@Controller('new-billing')
export class NewBillingController {
  constructor(private readonly newBillingService: NewBillingService) { }

  @Post()
  create(
    @Body() createNewBillingDto: CreateNewBillingDto[],
    @Query('patient_id') patient_id: number,
  ) {
    if (!patient_id) {
      return {
        status: 'failed',
        status_code: 400,
        message: 'patient_id is required',
      };
    }

    if (
      createNewBillingDto.some(
        (c) => !c.department_id || c.department_id.trim() === '',
      )
    ) {
      return {
        status: 'failed',
        status_code: 400,
        message: 'department_id is required for all charges',
      };
    }

    return this.newBillingService.create(createNewBillingDto, patient_id);
  }

  @Get('billing-summary-bills')
  async findAll(
    @Query('patient_id') patient_id: string,
    @Query('payment_module') payment_mode: string,
    @Query('bill_type') bill_type: string,
    @Query('limit') limit: number,
    @Query('page') page: number,
    @Query('searchText') searchText: string,
    @Query('appointment_id') appointment_id: string,
  ) {
    if (!patient_id) {
      return {
        status: 'failed',
        status_code: 400,
        message: 'Patient ID is required',
      };
    }

    if (bill_type && bill_type !== 'due' && bill_type !== 'paid') {
      return {
        status: 'failed',
        status_code: 400,
        message: 'Bill_Type must be due or paid',
      };
    }
    return this.newBillingService.findAll(
      patient_id,
      payment_mode,
      bill_type,
      limit || 10,
      page || 1,
      searchText,
      appointment_id,
    );
  }

  @Get('transaction-list')
  async findOne(
    @Query('patient_id') patient_id: number,
    @Query('payment_module') payment_module: string,
    @Query('limit') limit: number,
    @Query('page') page: number,
    @Query('appointment_id') appointment_id: number
  ) {
    if (!patient_id) {
      return {
        status: 'failed',
        status_code: 400,
        message: 'patient_id is required',
      };
    }
    return this.newBillingService.findtransactiondetails(
      patient_id,
      payment_module,
      limit || 10,
      page || 1,
      appointment_id
    );
  }

  @Post('patient-wallet')
  update(@Query('patient_id') patient_id: string) {
    return this.newBillingService.patient_wallet(patient_id);
  }

  @Post('coins-used')
  coins_used(
    @Query('patient_id') patient_id: number,
    @Query('coins_used') coins_used: number,
  ) {
    if (!patient_id || !coins_used) {
      return {
        status: 'failed',
        status_code: 400,
        message: 'Patient ID and coins_used is required',
      };
    }
    return this.newBillingService.coins_used(patient_id, coins_used);
  }

  @Post('/makePayment')
  @ApiOperation({ summary: 'Make a payment for a patient' })
  @ApiResponse({
    status: 201,
    description: 'Payment made successfully.',
  })
  @ApiResponse({
    status: 404,
    description: 'Patient charge not found.',
  })
  @ApiResponse({
    status: 400,
    description: 'Bad request. Validation errors or missing parameters.',
    type: ErrorResponse400,
  })
  @ApiResponse({
    status: 500,
    description: 'Internal server error.',
    type: ErrorResponse500,
  })
  makePaymentV3(@Body() createBillingDto: makepaymentV3) {
    console.log(Number(
      (
        Number(createBillingDto.amount_from_coins) +
        Number(createBillingDto.actual_amount_paid)
      ).toFixed(2),
    ), Number(createBillingDto.totalDue));

    // if (
    //   Number(
    //     (
    //       Number(createBillingDto.amount_from_coins) +
    //       Number(createBillingDto.actual_amount_paid)
    //     ).toFixed(2),
    //   ) != Number(createBillingDto.totalDue)
    // ) {
    //   return {
    //     status_code: 400,
    //     status: 'failed',
    //     message:
    //       'sum of amount_from_coins and actual_amount_paid must be equal to totaldue',
    //   };
    // }
    if (!createBillingDto.received_by_name) {
      return {
        status_code: process.env.ERROR_STATUS_CODE_PARAMS_MISSING_V2,
        status: process.env.ERROR_STATUS,
        message: process.env.ERROR_MESSAGE_PARAM_MISSING + 'received_by_name',
      };
    }
    if (!createBillingDto.paymentDetails) {
      return {
        status_code: process.env.ERROR_STATUS_CODE_PARAMS_MISSING_V2,
        status: process.env.ERROR_STATUS,
        message: process.env.ERROR_MESSAGE_PARAM_MISSING + 'paymentDetails',
      };
    }

    if (!createBillingDto.patient_details) {
      return {
        status_code: process.env.ERROR_STATUS_CODE_PARAMS_MISSING_V2,
        status: process.env.ERROR_STATUS,
        message: process.env.ERROR_MESSAGE_PARAM_MISSING + 'patient_details',
      };
    }
    if (!createBillingDto.payment_method) {
      return {
        status_code: process.env.ERROR_STATUS_CODE_PARAMS_MISSING_V2,
        status: process.env.ERROR_STATUS,
        message: process.env.ERROR_MESSAGE_PARAM_MISSING + 'payment_method',
      };
    }
    if (
      createBillingDto.payment_mode.toLocaleLowerCase() == 'card' &&
      !createBillingDto.card_division &&
      !createBillingDto.card_bank_name &&
      !createBillingDto.card_type &&
      !createBillingDto.card_transaction_id
    ) {
      return {
        status_code: process.env.ERROR_STATUS_CODE_PARAMS_MISSING_V2,
        status: process.env.ERROR_STATUS,
        message: process.env.ERROR_MESSAGE_PARAM_MISSING + 'card details',
      };
    }

    if (
      createBillingDto.payment_mode.toLocaleLowerCase() == 'net_banking' &&
      !createBillingDto.net_banking_division &&
      !createBillingDto.net_banking_transaction_id
    ) {
      return {
        status_code: process.env.ERROR_STATUS_CODE_PARAMS_MISSING_V2,
        status: process.env.ERROR_STATUS,
        message:
          process.env.ERROR_MESSAGE_PARAM_MISSING + 'net banking details',
      };
    }
    if (
      createBillingDto.payment_mode.toLocaleLowerCase() == 'upi' &&
      !createBillingDto.upi_id &&
      !createBillingDto.upi_transaction_id &&
      !createBillingDto.upi_bank_name
    ) {
      return {
        status_code: process.env.ERROR_STATUS_CODE_PARAMS_MISSING_V2,
        status: process.env.ERROR_STATUS,
        message: process.env.ERROR_MESSAGE_PARAM_MISSING + 'upi details',
      };
    }
    return this.newBillingService.makePaymentV3(createBillingDto);
  }

  @Get('get-transaction-details')
  gettransactiondata(
    @Query('hospital_id') hospital_id: number,
    @Query('hos_transaction_id') hos_transaction_id: string,
  ) {
    if (!hospital_id || !hos_transaction_id) {
      return {
        status: 'failed',
        status_code: 400,
        message: 'Hospital ID and Hos_Transaction ID is required',
      };
    }

    return this.newBillingService.get_transaction_details(
      hospital_id,
      hos_transaction_id,
    );
  }

  @Post('add-in-overallcharge')
  Addchargedata(
    @Query('aayush_unique_id') aayush_unique_id: string,
    @Query('hospital_id') hospital_id: number,

    @Body() body: any,
  ) {
    if (!aayush_unique_id || !hospital_id) {
      return {
        status: 'failed',
        status_code: 400,
        message: 'aayush_unique_id, hospital_id are required',
      };
    }
    if (
      Number(body.total_tax_amount) + Number(body.overall_subtotal_amount) !=
      Number(body.total_billed_amount)
    ) {
      return {
        status: 'failed',
        status_code: 400,
        message:
          'sum of subtotal and tax amount must be equal to billed amount',
      };
    }
    return this.newBillingService.add_overall_charges(
      aayush_unique_id,
      hospital_id,
      body,
    );
  }

  @Post('update-in-overallcharge')
  Updatechargedata(
    @Query('aayush_unique_id') aayush_unique_id: string,
    @Query('hospital_id') hospital_id: number,
    @Body() body: any,
  ) {
    if (!aayush_unique_id || !hospital_id) {
      return {
        status: 'failed',
        status_code: 400,
        message: 'aayush_unique_id, hospital_id are required',
      };
    }

    return this.newBillingService.update_overall_charges(
      aayush_unique_id,
      hospital_id,
      body,
    );
  }

  @Get('/app')
  async findApp(
    @Query('patient_id') patient_id: number,
    @Query('hospital_id') hospital_id: number,
    @Query('module') module: string,
  ) {
    if (!patient_id) {
      return {
        status: 'failed',
        status_code: 400,
        message: 'patient_id is required',
      };
    }

    if (!hospital_id) {
      return {
        status: 'failed',
        status_code: 400,
        message: 'hospital_id is required',
      };
    }

    return this.newBillingService.finddepartment_id(
      patient_id,
      hospital_id,
      module,
    );
  }

  @Get('dashboard')
  async dashboard(
    @Query('limit', ParseIntPipe) limit: number,
    @Query('page', ParseIntPipe) page: number,
    @Query('payment_status') payment_status: string,
    @Query('searchText') searchText: string,
  ) {
    if (
      payment_status &&
      payment_status !== 'paid' &&
      payment_status !== 'partially_paid' &&
      payment_status !== 'due'
    ) {
      console.log(
        payment_status &&
        payment_status !== 'paid' &&
        payment_status !== 'partially_paid' &&
        payment_status !== 'due',
        'check',
        payment_status,
      );

      return {
        status: 'failed',
        status_code: 400,
        message: 'payment_status must be due or paid or partially_paid',
      };
    }
    return this.newBillingService.overall_dashboard_data(
      limit || 10,
      page || 1,
      payment_status,
      searchText,
    );
  }

  @Get('dashboard-mongo-data')
  dashboardtransactiondata(
    @Query('limit') limit: number,
    @Query('page') page: number,
    @Query('search') search: string,
    @Query('start_date') start_date: any,
    @Query('end_date') end_date: any,
  ) {
    return this.newBillingService.dashboard_mongo_data(
      limit || 10,
      page || 1,
      search,
      start_date,
      end_date,
    );
  }

  @Get('dashboard-count')
  dashboardcount(@Query('hospital_id') hospital_id: number) {
    if (!hospital_id) {
      return {
        status: 'failed',
        status_code: 400,
        message: 'hospital_id is required',
      };
    }
    return this.newBillingService.dashboard_count(hospital_id);
  }

  @Get('patient-balance')
  balance(@Query('aayush_unique_id') aayush_unique_id: string) {
    if (!aayush_unique_id) {
      return {
        status: 'failed',
        status_code: 400,
        message: 'aayush_unique_id is required',
      };
    }
    return this.newBillingService.balance_by_patient(aayush_unique_id);
  }

  @Post('phr-patient-wallet')
  phrwallet(@Query('aayush_unique_id') aayush_unique_id: string) {
    return this.newBillingService.phr_patient_wallet(aayush_unique_id);
  }

  @Post('phr-coins-used')
  phr_coins_used(
    @Query('aayush_unique_id') aayush_unique_id: string,
    @Query('coins_used') coins_used: number,
  ) {
    if (!aayush_unique_id || !coins_used) {
      return {
        status: 'failed',
        status_code: 400,
        message: 'aayush_unique_id and coins_used is required',
      };
    }
    return this.newBillingService.phr_coins_used(aayush_unique_id, coins_used);
  }

  @Get('phr-transaction-list')
  async phrfindOne(
    @Query('aayush_unique_id') aayush_unique_id: number,
    @Query('payment_module') payment_module: string,
    @Query('limit') limit: number,
    @Query('page') page: number,
  ) {
    if (!aayush_unique_id) {
      return {
        status: 'failed',
        status_code: 400,
        message: 'aayush_unique_id is required',
      };
    }
    return this.newBillingService.phr_findtransactiondetails(
      aayush_unique_id,
      payment_module,
      limit || 10,
      page || 1,
    );
  }

  @Get('phr-billing-summary-bills')
  async phrfindAll(
    @Query('aayush_unique_id') aayush_unique_id: string,
    @Query('payment_module') payment_mode: string,
    @Query('bill_type') bill_type: string,
    @Query('limit') limit: number,
    @Query('page') page: number,
    @Query('searchText') searchText: string,
  ) {
    if (!aayush_unique_id) {
      return {
        status: 'failed',
        status_code: 400,
        message: 'aayush_unique_id is required',
      };
    }

    if (bill_type && bill_type !== 'due' && bill_type !== 'paid') {
      return {
        status: 'failed',
        status_code: 400,
        message: 'Bill_Type must be due or paid',
      };
    }
    return this.newBillingService.findAll(
      aayush_unique_id,
      payment_mode,
      bill_type,
      limit || 10,
      page || 1,
      searchText,
    );
  }

  @Get('phr-wallet-transactions')
  async phr_wallet_transactions(
    @Query('aayush_unique_id') aayush_unique_id: string,
    @Query('transaction_status') transaction_status: string,
  ) {
    if (!aayush_unique_id) {
      return {
        status: 'failed',
        status_code: 400,
        message: 'aayush_unique_id is required',
      };
    }
    return this.newBillingService.phr_wallet_credit_transactions(
      aayush_unique_id,
      transaction_status,
    );
  }

  @Delete('delete-charges')
  async delete_additional_charges(
    @Query('patient_charge_id') patient_charge_id: number,
    @Query('opd_id') opd_id: string,
    @Query('hospital_id') hospital_id: number,
    @Query('ipd_id') ipd_id: any,

  ) {
    if (!patient_charge_id && (!opd_id || !ipd_id)) {
      return {
        status: 'failed',
        status_code: 400,
        message: 'patient_charge_id and opd_id/ipd_id are required',
      };
    }
    return this.newBillingService.remove(
      patient_charge_id,
      opd_id,
      hospital_id, ipd_id
    );
  }
  // @Get('getmongodata')
  // async getmongodata(
  //   @Query('transId') transId: string,
  // ) {

  //   return this.newBillingService.addtransactionInfo(transId);
  // }


  @Get('coin-value')
  async coinValue() {
    return this.newBillingService.coinValue();
  }
}
