#include <iostream>
#include <fstream>
#include <vector>
#include <sstream>

using namespace std;

class Loan {
private:
    int loanId;
    double loanAmount;
    double interestRate;
    int loanTerms;
    string loanStatus;
    string borrowerDetails;

public:
    Loan(int id, double amount, double rate, int terms, string status, string details)
        : loanId(id), loanAmount(amount), interestRate(rate), loanTerms(terms), loanStatus(status), borrowerDetails(details) {}

    int getLoanId() const {
        return loanId;
    }

    double getLoanAmount() const {
        return loanAmount;
    }

    double getInterestRate() const {
        return interestRate;
    }

    int getLoanTerms() const {
        return loanTerms;
    }

    string getLoanStatus() const {
        return loanStatus;
    }

    string getBorrowerDetails() const {
        return borrowerDetails;
    }
};

class LoanManagementSystem {
private:
    vector<Loan> loans;

public:
    void addLoan(const Loan& loan) {
        loans.push_back(loan);
    }

    void updateLoan(int loanId, double newAmount, double newRate, int newTerms, string newStatus, string newDetails) {
        for (Loan& loan : loans) {
            if (loan.getLoanId() == loanId) {
                loan = Loan(loanId, newAmount, newRate, newTerms, newStatus, newDetails);
                cout << "Loan updated successfully." << endl;
                return;
            }
        }
        cout << "Loan not found." << endl;
    }

    void displayLoans() const {
        for (const Loan& loan : loans) {
            cout << "Loan ID: " << loan.getLoanId() << endl;
            cout << "Loan Amount: $" << loan.getLoanAmount() << endl;
            cout << "Interest Rate: " << loan.getInterestRate() << "%" << endl;
            cout << "Loan Terms: " << loan.getLoanTerms() << " months" << endl;
            cout << "Loan Status: " << loan.getLoanStatus() << endl;
            cout << "Borrower Details: " << loan.getBorrowerDetails() << endl;
            cout << "------------------------" << endl;
        }
    }

    void deleteLoan(int loanId) {
        for (auto it = loans.begin(); it != loans.end(); ++it) {
            if (it->getLoanId() == loanId) {
                loans.erase(it);
                cout << "Loan deleted successfully." << endl;
                return;
            }
        }
        cout << "Loan not found." << endl;
    }

    void saveLoansToFile(const string& filename) const {
        ofstream file(filename);
        if (file.is_open()) {
            for (const Loan& loan : loans) {
                file << loan.getLoanId() << "," << loan.getLoanAmount() << "," << loan.getInterestRate() << ","
                     << loan.getLoanTerms() << "," << loan.getLoanStatus() << "," << loan.getBorrowerDetails() << endl;
            }
            file.close();
            cout << "Loans saved to file successfully." << endl;
        } else {
            cout << "Unable to open the file." << endl;
        }
    }

    void loadLoansFromFile(const string& filename) {
        loans.clear();
        ifstream file(filename);
        if (file.is_open()) {
            int loanId, loanTerms;
            double loanAmount, interestRate;
            string loanStatus, borrowerDetails;
            string line;
            while (getline(file, line)) {
                stringstream ss(line);
                getline(ss, line, ',');
                loanId = stoi(line);
                getline(ss, line, ',');
                loanAmount = stod(line);
                getline(ss, line, ',');
                interestRate = stod(line);
                getline(ss, line, ',');
                loanTerms = stoi(line);
                getline(ss, line, ',');
                loanStatus = line;
                getline(ss, line, ',');
                borrowerDetails = line;

                Loan loan(loanId, loanAmount, interestRate, loanTerms, loanStatus, borrowerDetails);
                loans.push_back(loan);
            }
            file.close();
            cout << "Loans loaded from file successfully." << endl;
        } else {
            cout << "Unable to open the file." << endl;
        }
    }

    vector<Loan> searchLoansByStatus(const string& status) const {
        vector<Loan> result;
        for (const Loan& loan : loans) {
            if (loan.getLoanStatus() == status) {
                result.push_back(loan);
            }
        }
        return result;
    }

    double calculateTotalLoanAmount() const {
        double totalAmount = 0.0;
        for (const Loan& loan : loans) {
            totalAmount += loan.getLoanAmount();
        }
        return totalAmount;
    }

    double calculateAverageLoanAmount() const {
        double totalAmount = calculateTotalLoanAmount();
        return totalAmount / loans.size();
    }
};

void displayMenu() {
    cout << "===== Loan Management System =====" << endl;
    cout << "1) Manage Loans" << endl;
    cout << "2) Search Loans" << endl;
    cout << "3) Reports of Loans" << endl;
    cout << "4) Exit" << endl;
    cout << "Enter your choice: ";
}

int main() {
    LoanManagementSystem lms;

    while (true) {
        displayMenu();
        int choice;
        cin >> choice;

        switch (choice) {
            case 1: {
                cout << "===== Manage Loans =====" << endl;
                cout << "1) Add Loan" << endl;
                cout << "2) Update Loan" << endl;
                cout << "3) Display Loans" << endl;
                cout << "4) Delete Loan" << endl;
                cout << "5) Exit" << endl;
                cout << "Enter your choice: ";

                int manageChoice;
                cin >> manageChoice;

                switch (manageChoice) {
                    case 1: {
                        cout << "Enter Loan ID: ";
                        int loanId;
                        cin >> loanId;

                        cout << "Enter Loan Amount: $";
                        double loanAmount;
                        cin >> loanAmount;

                        cout << "Enter Interest Rate (%): ";
                        double interestRate;
                        cin >> interestRate;

                        cout << "Enter Loan Terms (months): ";
                        int loanTerms;
                        cin >> loanTerms;

                        cin.ignore();
                        cout << "Enter Loan Status: ";
                        string loanStatus;
                        getline(cin, loanStatus);

                        cout << "Enter Borrower Details: ";
                        string borrowerDetails;
                        getline(cin, borrowerDetails);

                        Loan loan(loanId, loanAmount, interestRate, loanTerms, loanStatus, borrowerDetails);
                        lms.addLoan(loan);
                        cout << "Loan added successfully." << endl;
                        break;
                    }
                    case 2: {
                        cout << "Enter Loan ID to update: ";
                        int loanId;
                        cin >> loanId;

                        cout << "Enter New Loan Amount: $";
                        double newLoanAmount;
                        cin >> newLoanAmount;

                        cout << "Enter New Interest Rate (%): ";
                        double newInterestRate;
                        cin >> newInterestRate;

                        cout << "Enter New Loan Terms (months): ";
                        int newLoanTerms;
                        cin >> newLoanTerms;

                        cin.ignore();
                        cout << "Enter New Loan Status: ";
                        string newLoanStatus;
                        getline(cin, newLoanStatus);

                        cout << "Enter New Borrower Details: ";
                        string newBorrowerDetails;
                        getline(cin, newBorrowerDetails);

                        lms.updateLoan(loanId, newLoanAmount, newInterestRate, newLoanTerms, newLoanStatus, newBorrowerDetails);
                        break;
                    }
                    case 3: {
                        cout << "===== Display Loans =====" << endl;
                        lms.displayLoans();
                        break;
                    }
                    case 4: {
                        cout << "Enter Loan ID to delete: ";
                        int loanId;
                        cin >> loanId;
                        lms.deleteLoan(loanId);
                        break;
                    }
                    case 5:
                        break;
                    default:
                        cout << "Invalid choice." << endl;
                        break;
                }
                break;
            }
            case 2: {
                cout << "===== Search Loans =====" << endl;
                cout << "Enter Loan Status to search: ";
                cin.ignore();
                string searchStatus;
                getline(cin, searchStatus);

                vector<Loan> searchResult = lms.searchLoansByStatus(searchStatus);
                if (searchResult.empty()) {
                    cout << "No loans found with the given status." << endl;
                } else {
                    cout << "Loans with status '" << searchStatus << "':" << endl;
                    for (const Loan& loan : searchResult) {
                        cout << "Loan ID: " << loan.getLoanId() << endl;
                        cout << "Loan Amount: $" << loan.getLoanAmount() << endl;
                        cout << "Interest Rate: " << loan.getInterestRate() << "%" << endl;
                        cout << "Loan Terms: " << loan.getLoanTerms() << " months" << endl;
                        cout << "Borrower Details: " << loan.getBorrowerDetails() << endl;
                        cout << "------------------------" << endl;
                    }
                }
                break;
            }
            case 3: {
                cout << "===== Reports of Loans =====" << endl;
                double totalAmount = lms.calculateTotalLoanAmount();
                double averageAmount = lms.calculateAverageLoanAmount();

                cout << "Total Loan Amount: $" << totalAmount << endl;
                cout << "Average Loan Amount: $" << averageAmount << endl;
                break;
            }
            case 4:
                lms.saveLoansToFile("loans.txt");
                cout << "Exiting the program. Goodbye!" << endl;
                return 0;
            default:
                cout << "Invalid choice." << endl;
                break;
        }
    }

    return 0;
}