package com.ruoyi.credit.controller;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.credit.domain.ServicePeriodLoan;
import com.ruoyi.credit.service.IServicePeriodLoanService;
import com.ruoyi.credit.service.ErrorHandlingService;
import com.ruoyi.credit.exception.BankSelectionException;

/**
 * 服务周期贷款管理Controller
 * 
 * @author ruoyi
 * @date 2025-12-24
 */
@RestController
@RequestMapping("/credit/service-period-loan")
public class ServicePeriodLoanController extends BaseController
{
    private static final Logger log = LoggerFactory.getLogger(ServicePeriodLoanController.class);

    @Autowired
    private IServicePeriodLoanService servicePeriodLoanService;

    @Autowired
    private ErrorHandlingService errorHandlingService;

    // ==================== 基础CRUD操作 ====================

    /**
     * 查询服务周期贷款关联列表
     */
    @PreAuthorize("@ss.hasPermi('credit:service-period-loan:list')")
    @GetMapping("/list")
    public TableDataInfo list(ServicePeriodLoan servicePeriodLoan)
    {
        startPage();
        List<ServicePeriodLoan> list = servicePeriodLoanService.selectServicePeriodLoanList(servicePeriodLoan);
        
        // 为每个贷款记录添加银行选择状态
        for (ServicePeriodLoan loan : list) {
            loan.setRemark(getBankSelectionStatus(loan));
        }
        
        return getDataTable(list);
    }

    /**
     * 获取服务周期贷款关联详细信息
     */
    @PreAuthorize("@ss.hasPermi('credit:service-period-loan:query')")
    @GetMapping(value = "/{linkId}")
    public AjaxResult getInfo(@PathVariable("linkId") Long linkId)
    {
        ServicePeriodLoan loan = servicePeriodLoanService.selectServicePeriodLoanByLinkId(linkId);
        if (loan != null) {
            // 添加银行选择状态信息
            Map<String, Object> result = new HashMap<>();
            result.put("loan", loan);
            result.put("bankSelectionStatus", getBankSelectionStatus(loan));
            result.put("canQuickSubmit", canQuickSubmit(loan));
            return success(result);
        }
        return success(loan);
    }

    /**
     * 根据服务周期ID查询贷款列表
     */
    @PreAuthorize("@ss.hasPermi('credit:service-period-loan:query')")
    @GetMapping("/by-period/{servicePeriodId}")
    public AjaxResult getByServicePeriodId(@PathVariable("servicePeriodId") Long servicePeriodId)
    {
        List<ServicePeriodLoan> loans = servicePeriodLoanService.selectServicePeriodLoansByPeriodId(servicePeriodId);
        
        // 为每个贷款记录添加银行选择状态
        for (ServicePeriodLoan loan : loans) {
            loan.setRemark(getBankSelectionStatus(loan));
        }
        
        return success(loans);
    }

    // ==================== 银行选择逻辑优化接口 ====================

    /**
     * 创建包含银行选择的贷款申请
     * 支持在申请时同时选择银行和填写提交说明
     */
    @PreAuthorize("@ss.hasPermi('credit:service-period-loan:add')")
    @Log(title = "申请贷款（含银行选择）", businessType = BusinessType.INSERT)
    @PostMapping("/apply-with-bank-selection")
    public AjaxResult applyLoanWithBankSelection(@RequestBody LoanApplicationRequest request)
    {
        try {
            // 验证必要参数
            if (request.getServicePeriodId() == null) {
                return error("服务周期ID不能为空");
            }
            if (request.getLoanAmount() == null || request.getLoanAmount().compareTo(BigDecimal.ZERO) <= 0) {
                return error("贷款金额必须大于0");
            }

            // 使用错误处理服务进行银行信息验证
            ServicePeriodLoan tempLoan = new ServicePeriodLoan();
            tempLoan.setBankInstitutionId(request.getBankInstitutionId());
            tempLoan.setBankInstitutionName(request.getBankInstitutionName());
            tempLoan.setSubmitComments(request.getSubmitComments());
            tempLoan.setInterestRate(request.getInterestRate());
            tempLoan.setMonthlyPayment(request.getMonthlyPayment());
            // 设置银行选择时间（在验证之前设置）
            tempLoan.setBankSelectedTime(DateUtils.getNowDate());
            
            Map<String, Object> validationResult = errorHandlingService.validateBankInformation(tempLoan);
            if (!(Boolean) validationResult.get("valid")) {
                // 生成友好的错误提示
                Map<String, Object> context = new HashMap<>();
                context.put("bankName", request.getBankInstitutionName());
                context.put("loanAmount", request.getLoanAmount());
                
                Map<String, Object> friendlyError = errorHandlingService.generateFriendlyErrorMessage(
                    "BANK_INFO_MISSING", context);
                
                return AjaxResult.error((String) friendlyError.get("message"))
                    .put("errorType", friendlyError.get("errorType"))
                    .put("suggestions", validationResult.get("suggestions"))
                    .put("missingFields", validationResult.get("missingFields"));
            }

            // 构建贷款申请对象
            ServicePeriodLoan servicePeriodLoan = new ServicePeriodLoan();
            servicePeriodLoan.setServicePeriodId(request.getServicePeriodId());
            servicePeriodLoan.setLoanAmount(request.getLoanAmount());
            servicePeriodLoan.setLoanTermMonths(request.getLoanTermMonths());
            servicePeriodLoan.setLoanPurpose(request.getLoanPurpose());
            servicePeriodLoan.setBankInstitutionId(request.getBankInstitutionId());
            servicePeriodLoan.setBankInstitutionName(request.getBankInstitutionName());
            servicePeriodLoan.setSubmitComments(request.getSubmitComments());
            servicePeriodLoan.setInterestRate(request.getInterestRate());
            servicePeriodLoan.setMonthlyPayment(request.getMonthlyPayment());
            
            // 设置银行选择相关字段
            servicePeriodLoan.setBankSelectedTime(DateUtils.getNowDate());
            servicePeriodLoan.setQuickSubmitEnabled(true);
            
            // 调用服务层创建贷款申请
            Map<String, Object> result = servicePeriodLoanService.createLoanWithBankSelection(servicePeriodLoan);
            
            return success(result);
        } catch (BankSelectionException e) {
            log.error("银行选择相关错误", e);
            
            // 生成友好的错误提示
            Map<String, Object> context = new HashMap<>();
            context.put("bankName", request.getBankInstitutionName());
            context.put("loanAmount", request.getLoanAmount());
            
            Map<String, Object> friendlyError = errorHandlingService.generateFriendlyErrorMessage(
                e.getErrorType().name(), context);
            
            return AjaxResult.error((String) friendlyError.get("message"))
                .put("errorType", e.getErrorType().name())
                .put("retryable", e.isRetryable())
                .put("suggestion", e.getSuggestion());
        } catch (Exception e) {
            log.error("创建贷款申请失败", e);
            
            // 处理网络错误重试
            if (isNetworkError(e)) {
                Map<String, Object> retryResult = errorHandlingService.handleNetworkErrorRetry(
                    "创建贷款申请", 0, e);
                
                return AjaxResult.error((String) retryResult.get("message"))
                    .put("errorType", "NETWORK_ERROR")
                    .put("retryable", retryResult.get("shouldRetry"))
                    .put("waitTime", retryResult.get("waitTime"));
            }
            
            return error("创建贷款申请失败: " + e.getMessage());
        }
    }

    /**
     * 一键提交贷款到银行
     * 使用已保存的银行选择和提交说明直接提交
     */
    @PreAuthorize("@ss.hasPermi('credit:service-period-loan:submit')")
    @Log(title = "一键提交贷款", businessType = BusinessType.UPDATE)
    @PostMapping("/quick-submit/{linkId}")
    public AjaxResult quickSubmitToBank(@PathVariable("linkId") Long linkId)
    {
        try {
            // 验证贷款是否存在
            ServicePeriodLoan loan = servicePeriodLoanService.selectServicePeriodLoanByLinkId(linkId);
            if (loan == null) {
                return error("贷款记录不存在");
            }

            // 使用错误处理服务进行数据完整性验证
            Map<String, Object> validationResult = errorHandlingService.validateLoanSubmissionData(loan);
            if (!(Boolean) validationResult.get("valid")) {
                // 尝试自动修复数据不一致问题
                Map<String, Object> repairResult = errorHandlingService.autoRepairDataInconsistency(loan);
                
                if ((Boolean) repairResult.get("success")) {
                    // 修复成功，重新验证
                    ServicePeriodLoan repairedLoan = servicePeriodLoanService.selectServicePeriodLoanByLinkId(linkId);
                    validationResult = errorHandlingService.validateLoanSubmissionData(repairedLoan);
                    
                    if (!(Boolean) validationResult.get("valid")) {
                        // 修复后仍有问题
                        Map<String, Object> context = new HashMap<>();
                        context.put("loanNumber", loan.getLoanNumber());
                        context.put("bankName", loan.getBankInstitutionName());
                        
                        Map<String, Object> friendlyError = errorHandlingService.generateFriendlyErrorMessage(
                            "VALIDATION_ERROR", context);
                        
                        return AjaxResult.error((String) friendlyError.get("message"))
                            .put("errors", validationResult.get("errors"))
                            .put("warnings", validationResult.get("warnings"))
                            .put("repairAttempted", true)
                            .put("repairedItems", repairResult.get("repairedItems"));
                    } else {
                        // 修复成功，可以继续提交
                        loan = repairedLoan;
                    }
                } else {
                    // 修复失败
                    return AjaxResult.error("数据验证失败且自动修复失败: " + repairResult.get("message"))
                        .put("errors", validationResult.get("errors"))
                        .put("warnings", validationResult.get("warnings"));
                }
            }

            // 调用服务层一键提交
            Map<String, Object> result = servicePeriodLoanService.quickSubmitToBank(linkId);
            
            return success(result);
        } catch (BankSelectionException e) {
            log.error("银行选择相关错误: linkId={}", linkId, e);
            
            // 处理银行服务不可用的情况
            if (e.getErrorType() == BankSelectionException.ErrorType.BANK_SERVICE_UNAVAILABLE) {
                ServicePeriodLoan loan = servicePeriodLoanService.selectServicePeriodLoanByLinkId(linkId);
                Map<String, Object> alternativeResult = errorHandlingService.handleBankServiceUnavailable(
                    loan.getBankInstitutionId(), loan.getServicePeriodId());
                
                return AjaxResult.error(e.getMessage())
                    .put("errorType", "BANK_SERVICE_UNAVAILABLE")
                    .put("alternatives", alternativeResult.get("alternatives"))
                    .put("hasAlternatives", alternativeResult.get("hasAlternatives"))
                    .put("suggestion", alternativeResult.get("suggestion"));
            }
            
            Map<String, Object> context = new HashMap<>();
            context.put("loanNumber", linkId.toString());
            
            Map<String, Object> friendlyError = errorHandlingService.generateFriendlyErrorMessage(
                e.getErrorType().name(), context);
            
            return AjaxResult.error((String) friendlyError.get("message"))
                .put("errorType", e.getErrorType().name())
                .put("retryable", e.isRetryable())
                .put("suggestion", e.getSuggestion());
        } catch (Exception e) {
            log.error("一键提交贷款失败: linkId={}", linkId, e);
            
            // 处理网络错误重试
            if (isNetworkError(e)) {
                Map<String, Object> retryResult = errorHandlingService.handleNetworkErrorRetry(
                    "一键提交贷款", 0, e);
                
                return AjaxResult.error((String) retryResult.get("message"))
                    .put("errorType", "NETWORK_ERROR")
                    .put("retryable", retryResult.get("shouldRetry"))
                    .put("waitTime", retryResult.get("waitTime"));
            }
            
            return error("一键提交失败: " + e.getMessage());
        }
    }

    /**
     * 修改银行选择和提交说明
     * 允许用户在待提交状态下修改银行选择
     */
    @PreAuthorize("@ss.hasPermi('credit:service-period-loan:edit')")
    @Log(title = "修改银行选择", businessType = BusinessType.UPDATE)
    @PutMapping("/update-bank-selection/{linkId}")
    public AjaxResult updateBankSelection(@PathVariable("linkId") Long linkId, 
                                        @RequestBody UpdateBankSelectionRequest request)
    {
        try {
            // 验证贷款是否存在
            ServicePeriodLoan loan = servicePeriodLoanService.selectServicePeriodLoanByLinkId(linkId);
            if (loan == null) {
                return error("贷款记录不存在");
            }

            // 验证是否可以修改（只有待提交状态才能修改）
            if (!ServicePeriodLoan.STATUS_PENDING.equals(loan.getLoanStatus())) {
                return error("只有待提交状态的贷款才能修改银行选择");
            }

            // 验证必要参数
            if (request.getBankInstitutionId() == null) {
                return error("请选择银行机构");
            }

            // 记录银行选择变更历史
            String historyRecord = String.format("从银行[%s]变更为银行[%s]，时间：%s", 
                loan.getBankInstitutionName(), 
                request.getBankInstitutionName(),
                DateUtils.dateTimeNow());
            
            String existingHistory = loan.getBankSelectionHistory();
            if (StringUtils.isNotEmpty(existingHistory)) {
                loan.setBankSelectionHistory(existingHistory + ";" + historyRecord);
            } else {
                loan.setBankSelectionHistory(historyRecord);
            }

            // 更新银行选择信息
            loan.setBankInstitutionId(request.getBankInstitutionId());
            loan.setBankInstitutionName(request.getBankInstitutionName());
            loan.setSubmitComments(request.getSubmitComments());
            loan.setInterestRate(request.getInterestRate());
            loan.setMonthlyPayment(request.getMonthlyPayment());
            loan.setBankSelectedTime(DateUtils.getNowDate());

            // 调用服务层更新（支持历史记录）
            int result = servicePeriodLoanService.updateServicePeriodLoanWithHistory(loan);
            
            return toAjax(result);
        } catch (Exception e) {
            log.error("修改银行选择失败: linkId={}", linkId, e);
            return error("修改银行选择失败: " + e.getMessage());
        }
    }

    // ==================== 其他CRUD操作 ====================

    /**
     * 新增服务周期贷款关联
     */
    @PreAuthorize("@ss.hasPermi('credit:service-period-loan:add')")
    @Log(title = "服务周期贷款关联", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody ServicePeriodLoan servicePeriodLoan)
    {
        return toAjax(servicePeriodLoanService.insertServicePeriodLoan(servicePeriodLoan));
    }

    /**
     * 修改服务周期贷款关联
     */
    @PreAuthorize("@ss.hasPermi('credit:service-period-loan:edit')")
    @Log(title = "服务周期贷款关联", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody ServicePeriodLoan servicePeriodLoan)
    {
        return toAjax(servicePeriodLoanService.updateServicePeriodLoan(servicePeriodLoan));
    }

    /**
     * 删除服务周期贷款关联
     */
    @PreAuthorize("@ss.hasPermi('credit:service-period-loan:remove')")
    @Log(title = "服务周期贷款关联", businessType = BusinessType.DELETE)
    @DeleteMapping("/{linkIds}")
    public AjaxResult remove(@PathVariable Long[] linkIds)
    {
        return toAjax(servicePeriodLoanService.deleteServicePeriodLoanByLinkIds(linkIds));
    }

    // ==================== 辅助方法 ====================

    /**
     * 判断是否为网络错误
     */
    private boolean isNetworkError(Exception e) {
        if (e == null) return false;
        
        String message = e.getMessage();
        if (message == null) return false;
        
        return message.contains("timeout") || 
               message.contains("connection") || 
               message.contains("network") ||
               message.contains("ConnectException") ||
               message.contains("SocketTimeoutException");
    }

    /**
     * 全面验证贷款是否可以提交
     */
    private String validateLoanForSubmission(ServicePeriodLoan loan) {
        // 1. 验证贷款状态
        if (!ServicePeriodLoan.STATUS_PENDING.equals(loan.getLoanStatus())) {
            return "只有待提交状态的贷款才能提交，当前状态：" + loan.getLoanStatus();
        }

        // 2. 验证银行选择信息
        if (loan.getBankInstitutionId() == null) {
            return "银行信息缺失，请先选择银行";
        }

        if (StringUtils.isEmpty(loan.getBankInstitutionName())) {
            return "银行名称缺失，请重新选择银行";
        }

        // 3. 验证贷款基本信息
        if (loan.getLoanAmount() == null || loan.getLoanAmount().compareTo(BigDecimal.ZERO) <= 0) {
            return "贷款金额无效，必须大于0";
        }

        if (loan.getLoanTermMonths() == null || loan.getLoanTermMonths() <= 0) {
            return "贷款期限无效，必须大于0个月";
        }

        if (StringUtils.isEmpty(loan.getLoanPurpose())) {
            return "贷款用途不能为空";
        }

        // 4. 验证提交说明
        if (StringUtils.isEmpty(loan.getSubmitComments())) {
            return "提交说明不能为空，请填写提交给银行的说明信息";
        }

        if (loan.getSubmitComments().trim().length() < 10) {
            return "提交说明至少需要10个字符";
        }

        // 5. 验证利率和月还款额
        if (loan.getInterestRate() == null || loan.getInterestRate() <= 0) {
            return "利率信息无效，请重新选择银行";
        }

        if (loan.getMonthlyPayment() == null || loan.getMonthlyPayment().compareTo(BigDecimal.ZERO) <= 0) {
            return "月还款额信息无效，请重新选择银行";
        }

        // 6. 验证一键提交标志
        if (!Boolean.TRUE.equals(loan.getQuickSubmitEnabled())) {
            return "该贷款申请不支持一键提交，请检查申请信息";
        }

        // 7. 验证服务周期ID
        if (loan.getServicePeriodId() == null) {
            return "服务周期信息缺失";
        }

        return null; // 验证通过
    }

    // ==================== 错误处理相关接口 ====================

    /**
     * 检查银行选择状态
     */
    @PreAuthorize("@ss.hasPermi('credit:service-period-loan:query')")
    @GetMapping("/check-bank-status/{linkId}")
    public AjaxResult checkBankSelectionStatus(@PathVariable("linkId") Long linkId)
    {
        try {
            ServicePeriodLoan loan = servicePeriodLoanService.selectServicePeriodLoanByLinkId(linkId);
            if (loan == null) {
                return error("贷款记录不存在");
            }

            Map<String, Object> statusResult = errorHandlingService.checkAndRepairBankSelectionStatus(loan);
            
            return success(statusResult);
        } catch (Exception e) {
            log.error("检查银行选择状态失败: linkId={}", linkId, e);
            return error("检查状态失败: " + e.getMessage());
        }
    }

    /**
     * 自动修复数据不一致
     */
    @PreAuthorize("@ss.hasPermi('credit:service-period-loan:edit')")
    @PostMapping("/auto-repair/{linkId}")
    public AjaxResult autoRepairDataInconsistency(@PathVariable("linkId") Long linkId)
    {
        try {
            ServicePeriodLoan loan = servicePeriodLoanService.selectServicePeriodLoanByLinkId(linkId);
            if (loan == null) {
                return error("贷款记录不存在");
            }

            Map<String, Object> repairResult = errorHandlingService.autoRepairDataInconsistency(loan);
            
            return success(repairResult);
        } catch (Exception e) {
            log.error("自动修复数据不一致失败: linkId={}", linkId, e);
            return error("自动修复失败: " + e.getMessage());
        }
    }

    /**
     * 获取银行服务备选方案
     */
    @PreAuthorize("@ss.hasPermi('credit:service-period-loan:query')")
    @GetMapping("/bank-alternatives/{bankId}/{servicePeriodId}")
    public AjaxResult getBankAlternatives(@PathVariable("bankId") Long bankId, 
                                        @PathVariable("servicePeriodId") Long servicePeriodId)
    {
        try {
            Map<String, Object> alternativeResult = errorHandlingService.handleBankServiceUnavailable(bankId, servicePeriodId);
            
            return success(alternativeResult);
        } catch (Exception e) {
            log.error("获取银行备选方案失败: bankId={}, servicePeriodId={}", bankId, servicePeriodId, e);
            return error("获取备选方案失败: " + e.getMessage());
        }
    }

    /**
     * 验证贷款提交数据
     */
    @PreAuthorize("@ss.hasPermi('credit:service-period-loan:query')")
    @PostMapping("/validate-submission/{linkId}")
    public AjaxResult validateLoanSubmissionData(@PathVariable("linkId") Long linkId)
    {
        try {
            ServicePeriodLoan loan = servicePeriodLoanService.selectServicePeriodLoanByLinkId(linkId);
            if (loan == null) {
                return error("贷款记录不存在");
            }

            Map<String, Object> validationResult = errorHandlingService.validateLoanSubmissionData(loan);
            
            return success(validationResult);
        } catch (Exception e) {
            log.error("验证贷款提交数据失败: linkId={}", linkId, e);
            return error("验证失败: " + e.getMessage());
        }
    }

    /**
     * 获取银行选择状态
     */
    private String getBankSelectionStatus(ServicePeriodLoan loan) {
        if (loan.getBankInstitutionId() == null) {
            return "NOT_SELECTED"; // 未选择银行
        }
        
        if (ServicePeriodLoan.STATUS_PENDING.equals(loan.getLoanStatus())) {
            return "SELECTED_PENDING"; // 已选择银行，待提交
        }
        
        if (ServicePeriodLoan.STATUS_SUBMITTED.equals(loan.getLoanStatus()) || 
            ServicePeriodLoan.APPROVAL_SUBMITTED.equals(loan.getApprovalStatus())) {
            return "SUBMITTED"; // 已提交至银行
        }
        
        return "UNKNOWN"; // 未知状态
    }

    /**
     * 判断是否可以一键提交
     */
    private boolean canQuickSubmit(ServicePeriodLoan loan) {
        return validateLoanForSubmission(loan) == null;
    }

    // ==================== 请求对象定义 ====================

    /**
     * 贷款申请请求对象
     */
    public static class LoanApplicationRequest {
        private Long servicePeriodId;
        private BigDecimal loanAmount;
        private Integer loanTermMonths;
        private String loanPurpose;
        private Long bankInstitutionId;
        private String bankInstitutionName;
        private String submitComments;
        private Double interestRate;
        private BigDecimal monthlyPayment;

        // getters and setters
        public Long getServicePeriodId() { return servicePeriodId; }
        public void setServicePeriodId(Long servicePeriodId) { this.servicePeriodId = servicePeriodId; }
        public BigDecimal getLoanAmount() { return loanAmount; }
        public void setLoanAmount(BigDecimal loanAmount) { this.loanAmount = loanAmount; }
        public Integer getLoanTermMonths() { return loanTermMonths; }
        public void setLoanTermMonths(Integer loanTermMonths) { this.loanTermMonths = loanTermMonths; }
        public String getLoanPurpose() { return loanPurpose; }
        public void setLoanPurpose(String loanPurpose) { this.loanPurpose = loanPurpose; }
        public Long getBankInstitutionId() { return bankInstitutionId; }
        public void setBankInstitutionId(Long bankInstitutionId) { this.bankInstitutionId = bankInstitutionId; }
        public String getBankInstitutionName() { return bankInstitutionName; }
        public void setBankInstitutionName(String bankInstitutionName) { this.bankInstitutionName = bankInstitutionName; }
        public String getSubmitComments() { return submitComments; }
        public void setSubmitComments(String submitComments) { this.submitComments = submitComments; }
        public Double getInterestRate() { return interestRate; }
        public void setInterestRate(Double interestRate) { this.interestRate = interestRate; }
        public BigDecimal getMonthlyPayment() { return monthlyPayment; }
        public void setMonthlyPayment(BigDecimal monthlyPayment) { this.monthlyPayment = monthlyPayment; }
    }

    /**
     * 更新银行选择请求对象
     */
    public static class UpdateBankSelectionRequest {
        private Long bankInstitutionId;
        private String bankInstitutionName;
        private String submitComments;
        private Double interestRate;
        private BigDecimal monthlyPayment;

        // getters and setters
        public Long getBankInstitutionId() { return bankInstitutionId; }
        public void setBankInstitutionId(Long bankInstitutionId) { this.bankInstitutionId = bankInstitutionId; }
        public String getBankInstitutionName() { return bankInstitutionName; }
        public void setBankInstitutionName(String bankInstitutionName) { this.bankInstitutionName = bankInstitutionName; }
        public String getSubmitComments() { return submitComments; }
        public void setSubmitComments(String submitComments) { this.submitComments = submitComments; }
        public Double getInterestRate() { return interestRate; }
        public void setInterestRate(Double interestRate) { this.interestRate = interestRate; }
        public BigDecimal getMonthlyPayment() { return monthlyPayment; }
        public void setMonthlyPayment(BigDecimal monthlyPayment) { this.monthlyPayment = monthlyPayment; }
    }
}