package handlers

import (
	"fmt"

	"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
	"github.com/gofiber/fiber/v2"
)

// InitiateDeposit godoc
// @Summary Initiate a deposit
// @Description Starts a new deposit process using Chapa payment gateway
// @Tags Chapa
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param request body domain.ChapaDepositRequestPayload true "Deposit request"
// @Success 200 {object} domain.ChapaDepositResponse
// @Failure 400 {object} domain.ErrorResponse
// @Failure 500 {object} domain.ErrorResponse
// @Router /api/v1/chapa/payments/deposit [post]
func (h *Handler) InitiateDeposit(c *fiber.Ctx) error {
	// Get user ID from context (set by your auth middleware)
	userID, ok := c.Locals("user_id").(int64)
	if !ok {
		return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{
			Error: "invalid user ID",
		})
	}

	var req domain.ChapaDepositRequestPayload

	if err := c.BodyParser(&req); err != nil {
		fmt.Sprintln("We first first are here init Chapa payment")
		return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{
			Error: err.Error(),
		})
	}

	amount := domain.Currency(req.Amount * 100)

	fmt.Sprintln("We are here init Chapa payment")

	checkoutURL, err := h.chapaSvc.InitiateDeposit(c.Context(), userID, amount)
	if err != nil {
		return c.Status(fiber.StatusInternalServerError).JSON(domain.ErrorResponse{
			Error:   err.Error(),
			Message: checkoutURL,
		})
	}

	return c.Status(fiber.StatusOK).JSON(domain.ChapaDepositResponse{
		CheckoutURL: checkoutURL,
	})
}

// WebhookCallback godoc
// @Summary Chapa payment webhook callback (used by Chapa)
// @Description Handles payment notifications from Chapa
// @Tags Chapa
// @Accept json
// @Produce json
// @Param request body domain.ChapaWebhookPayload true "Webhook payload"
// @Success 200 {object} map[string]interface{}
// @Failure 400 {object} domain.ErrorResponse
// @Failure 500 {object} domain.ErrorResponse
// @Router /api/v1/chapa/payments/webhook/verify [post]
func (h *Handler) WebhookCallback(c *fiber.Ctx) error {

	chapaTransactionType := new(domain.ChapaTransactionType)

	if parseTypeErr := c.BodyParser(chapaTransactionType); parseTypeErr != nil {
		return domain.UnProcessableEntityResponse(c)
	}

	switch chapaTransactionType.Type {
	case h.Cfg.CHAPA_TRANSFER_TYPE:
		chapaTransferVerificationRequest := new(domain.ChapaWebHookTransfer)

		if err := c.BodyParser(chapaTransferVerificationRequest); err != nil {
			return domain.UnProcessableEntityResponse(c)
		}

		err := h.chapaSvc.HandleVerifyDepositWebhook(c.Context(), *chapaTransferVerificationRequest)
		if err != nil {
			return c.Status(fiber.StatusInternalServerError).JSON(domain.ErrorResponse{
				Message: "Failed to verify Chapa depposit",
				Error:   err.Error(),
			})
		}

		return c.Status(fiber.StatusOK).JSON(domain.Response{
			StatusCode: 200,
			Message:    "Chapa deposit transaction verified successfully",
			Data:       chapaTransferVerificationRequest,
			Success:    true,
		})
	case h.Cfg.CHAPA_PAYMENT_TYPE:
		chapaPaymentVerificationRequest := new(domain.ChapaWebHookPayment)
		if err := c.BodyParser(chapaPaymentVerificationRequest); err != nil {
			return domain.UnProcessableEntityResponse(c)
		}

		err := h.chapaSvc.HandleVerifyWithdrawWebhook(c.Context(), *chapaPaymentVerificationRequest)
		if err != nil {
			return domain.UnExpectedErrorResponse(c)
		}

		return c.Status(fiber.StatusOK).JSON(domain.Response{
			StatusCode: 200,
			Message:    "Chapa withdrawal transaction verified successfully",
			Data:       chapaPaymentVerificationRequest,
			Success:    true,
		})

	}

	// Return a 400 Bad Request if the type does not match any known case
	return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{
		Message: "Invalid Chapa webhook type",
		Error:   "Unknown transaction type",
	})
}

// VerifyPayment godoc
// @Summary Verify a payment manually
// @Description Manually verify a payment using Chapa's API
// @Tags Chapa
// @Accept json
// @Produce json
// @Param tx_ref path string true "Transaction Reference"
// @Success 200 {object} domain.ChapaVerificationResponse
// @Failure 400 {object} domain.ErrorResponse
// @Failure 500 {object} domain.ErrorResponse
// @Router /api/v1/chapa/payments/manual/verify/{tx_ref} [get]
func (h *Handler) ManualVerifyTransaction(c *fiber.Ctx) error {
	txRef := c.Params("tx_ref")
	if txRef == "" {
		return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{
			Message: "Failed to verify Chapa transaction",
			Error:   "Transaction reference is required",
		})
	}

	verification, err := h.chapaSvc.ManualVerifTransaction(c.Context(), txRef)
	if err != nil {
		return c.Status(fiber.StatusInternalServerError).JSON(domain.ErrorResponse{
			Message: "Failed to verify Chapa transaction",
			Error:   err.Error(),
		})
	}

	return c.Status(fiber.StatusOK).JSON(domain.ChapaVerificationResponse{
		Status:   string(verification.Status),
		Amount:   verification.Amount,
		Currency: verification.Currency,
		TxRef:    txRef,
	})
}

// GetSupportedBanks godoc
// @Summary Get supported banks
// @Description Get list of banks supported by Chapa
// @Tags Chapa
// @Accept json
// @Produce json
// @Success 200 {object} domain.Response
// @Failure 500 {object} domain.ErrorResponse
// @Router /api/v1/chapa/banks [get]
func (h *Handler) GetSupportedBanks(c *fiber.Ctx) error {
	banks, err := h.chapaSvc.GetSupportedBanks(c.Context())
	if err != nil {
		return c.Status(fiber.StatusInternalServerError).JSON(domain.ErrorResponse{
			Error:   err.Error(),
			Message: "Failed to fetch banks",
		})
	}

	return c.Status(fiber.StatusOK).JSON(domain.Response{
		Message:    "Banks fetched successfully",
		StatusCode: 200,
		Success:    true,
		Data:       banks,
	})
}

// InitiateWithdrawal initiates a withdrawal request via Chapa payment gateway
// @Summary Initiate a withdrawal
// @Description Initiates a withdrawal request to transfer funds to a bank account via Chapa
// @Tags Chapa
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param request body domain.ChapaWithdrawalRequest true "Withdrawal request details"
// @Success 201 {object} domain.Response "Chapa withdrawal process initiated successfully"
// @Failure 400 {object} domain.ErrorResponse "Invalid request body"
// @Failure 401 {object} domain.ErrorResponse "Unauthorized"
// @Failure 422 {object} domain.ErrorResponse "Unprocessable entity"
// @Failure 500 {object} domain.ErrorResponse "Internal server error"
// @Router /api/v1/chapa/payments/withdraw [post]
func (h *Handler) InitiateWithdrawal(c *fiber.Ctx) error {
	userID, ok := c.Locals("user_id").(int64)
	if !ok {
		return domain.UnProcessableEntityResponse(c)
	}

	var req domain.ChapaWithdrawalRequest
	if err := c.BodyParser(&req); err != nil {
		return domain.UnProcessableEntityResponse(c)
	}

	withdrawal, err := h.chapaSvc.InitiateWithdrawal(c.Context(), userID, req)
	if err != nil {
		return c.Status(fiber.StatusInternalServerError).JSON(domain.ErrorResponse{
			Message: "Failed to initiate Chapa withdrawal",
			Error:   err.Error(),
		})
	}

	return c.Status(fiber.StatusCreated).JSON(domain.Response{
		Message:    "Chapa withdrawal process initiated successfully",
		StatusCode: 201,
		Success:    true,
		Data:       withdrawal,
	})
}
