/*
 * @Author: Student author@example.com
 * @Date: 2025-01-02 23:22:59
 * @LastEditors: Student author@example.com
 * @LastEditTime: 2025-01-03 19:09:33
 * @FilePath: \LibraryManageSystem\src\LibrarySystem.cpp
 * @Description: Coding with UTF-8
 *
 * Copyright (c) 2025 by Student, All Rights Reserved.
 */
#include "../include/LibrarySystem.h"
#include <iostream>
#include <iomanip>

/**
 * @brief 析构函数,退出登录
 */
LibrarySystem::~LibrarySystem()
{
    logout();
}

/**
 * @brief 判断当前用户是否为管理员
 * @return 如果是管理员返回true,否则返回false
 */
bool LibrarySystem::isAdmin() const
{
    return currentUser && currentUser->getType() == MemberType::ADMIN;
}

/**
 * @brief 用户登录
 * @param id 用户ID
 * @param password 密码
 * @return 登录成功返回true,失败返回false
 */
bool LibrarySystem::login(const std::string &id, const std::string &password)
{
    std::cout << "尝试登录: " << id << std::endl; // 调试信息
    currentUser = memberManager.authenticate(id, password);
    if (currentUser)
    {
        std::cout << "认证成功" << std::endl; // 调试信息
        currentUser->loadBorrowRecords();
        currentUser->updateBorrowRecords();
        return true;
    }
    std::cout << "认证失败" << std::endl; // 调试信息
    return false;
}

/**
 * @brief 用户登出
 */
void LibrarySystem::logout()
{
    currentUser = nullptr;
}

/**
 * @brief 添加新图书
 * @param id 图书ID
 * @param title 书名
 * @param author 作者
 * @param library 所在图书馆
 * @param stock 库存数量
 * @return 添加成功返回true,失败返回false
 */
bool LibrarySystem::addBook(const std::string &id, const std::string &title,
                            const std::string &author, const std::string &library, int stock)
{
    std::cout << "尝试添加书籍" << id << std::endl;

    // 检查是否已存在相同ID的图书
    if (bookManager.findBook(id))
    {
        std::cout << "ID为 " << id << " 的书已经存在" << std::endl;
        return false;
    }

    Book *newBook = new Book(id, title, author, library,
                             BookCategory::OTHER,
                             "",
                             stock);

    bool success = bookManager.addBook(newBook);
    if (success)
    {
        std::cout << "添加书籍成功" << std::endl;
        bookManager.saveToFile();
    }
    else
    {
        std::cout << "添加书籍失败" << std::endl;
        delete newBook; // 清理内存
    }
    return success;
}

/**
 * @brief 下架图书
 * @param bookId 要下架的图书ID
 * @return 下架成功返回true,失败返回false
 */
bool LibrarySystem::removeBook(const std::string &bookId)
{
    std::cout << " 开始下架图书操作" << std::endl;

    if (!isAdmin())
    {
        std::cout << " 非管理员权限" << std::endl;
        return false;
    }

    Book *book = bookManager.findBook(bookId);
    if (!book)
    {
        std::cout << " 图书不存在" << std::endl;
        return false;
    }

    // 检查是否有人借阅
    if (book->getCurrentStock() != book->getTotalStock())
    {
        std::cout << " 图书仍有借出，无法下架" << std::endl;
        return false;
    }

    // 读取所有行并重写文件，跳过要删除的图书
    std::ifstream inFile("../data/books.csv");
    std::ofstream tempFile("../data/books_temp.csv");

    if (!inFile || !tempFile)
    {
        std::cout << " 无法打开文件" << std::endl;
        return false;
    }

    std::string line;
    bool found = false;
    while (std::getline(inFile, line))
    {
        // 检查行是否以图书ID开头
        if (line.find(bookId + ",") == 0)
        {
            found = true;
            continue; // 跳过这一行
        }
        tempFile << line << "\n";
    }

    inFile.close();
    tempFile.close();

    if (!found)
    {
        std::cout << " 在文件中未找到图书" << std::endl;
        std::remove("../data/books_temp.csv");
        return false;
    }

    // 替换原文件
    if (std::remove("../data/books.csv") != 0)
    {
        std::cout << " 删除原文件失败" << std::endl;
        return false;
    }

    if (std::rename("../data/books_temp.csv", "../data/books.csv") != 0)
    {
        std::cout << " 重命名临时文件失败" << std::endl;
        return false;
    }

    std::cout << " 文件操作完成，重新加载图书数据" << std::endl;
    bookManager.loadFromFile();
    return true;
}

/**
 * @brief 封禁用户
 * @param userId 要封禁的用户ID
 * @return 封禁成功返回true,失败返回false
 */
bool LibrarySystem::banUser(const std::string &userId)
{
    if (!isAdmin())
        return false;

    Member *member = memberManager.findMember(userId);
    if (member && member->getType() != MemberType::ADMIN)
    {
        member->updateCreditScore(-100); // 将信用分降为0即视为封禁
        return true;
    }
    return false;
}

/**
 * @brief 检查超期图书
 */
void LibrarySystem::checkOverdueBooks()
{
    if (!isAdmin())
        return;

    std::cout << "超期图书列表：" << std::endl;
    std::cout << std::setw(10) << "用户ID"
              << std::setw(20) << "书籍ID"
              << std::setw(15) << "超期天数" << std::endl;

    LinkList overdueList = memberManager.getOverdueMembers();
    for (int i = 1; i <= overdueList.length(); i++)
    {
        Member *member = reinterpret_cast<Member *>(overdueList.getPointer(i)->data);
        // 显示该用户的超期图书信息
        // ... 具体实现
    }
}

/**
 * @brief 借阅图书
 * @param bookId 要借阅的图书ID
 * @return 借阅成功返回true,失败返回false
 */
bool LibrarySystem::borrowBook(const std::string &bookId)
{
    if (!currentUser)
        return false;

    Book *book = bookManager.findBook(bookId);
    if (book && book->isAvailable() && currentUser->canBorrowMore())
    {
        if (bookManager.borrowBook(bookId, currentUser->getPhone()) &&
            currentUser->borrowBook(bookId))
        {
            currentUser->saveBorrowRecords();
            bookManager.saveToFile();
            return true;
        }
    }
    return false;
}

/**
 * @brief 归还图书
 * @param bookId 要归还的图书ID
 * @return 归还成功返回true,失败返回false
 */
bool LibrarySystem::returnBook(const std::string &bookId)
{
    if (!currentUser)
        return false;

    // 先更新用户的借阅记录
    if (currentUser->returnBook(bookId))
    {
        // 然后更新图书库存
        return bookManager.returnBook(bookId, currentUser->getPhone());
    }
    return false;
}

/**
 * @brief 查看已借图书
 */
void LibrarySystem::viewBorrowedBooks()
{
    if (!currentUser)
        return;

    std::cout << "当前借阅的图书：" << std::endl;
    std::cout << std::setw(10) << "书号"
              << std::setw(20) << "书名"
              << std::setw(15) << "借阅日期"
              << std::setw(15) << "应还日期" << std::endl;

    // 显示当前用户借阅的所有图书
}

/**
 * @brief 搜索图书
 * @param keyword 搜索关键词
 */
void LibrarySystem::searchBooks(const std::string &keyword)
{
    LinkList results = bookManager.searchBooks(keyword);
    if (results.length() == 0)
    {
        std::cout << "未找到相关图书" << std::endl;
        return;
    }

    std::cout << "搜索结果：" << std::endl;
    for (int i = 1; i <= results.length(); i++)
    {
        Book *book = reinterpret_cast<Book *>(results.getPointer(i)->data);
        std::cout << std::setw(10) << book->getBookId()
                  << std::setw(20) << book->getTitle()
                  << std::setw(15) << book->getAuthor()
                  << std::setw(10) << book->getCurrentStock() << "/"
                  << book->getTotalStock() << std::endl;
    }
}

/**
 * @brief 显示管理员菜单
 */
void LibrarySystem::showAdminMenu()
{
    std::cout << "\n=== 图书管理系统（管理员模式）===" << std::endl;
    std::cout << "1. 添加图书" << std::endl;
    std::cout << "2. 下架图书" << std::endl;
    std::cout << "3. 修改图书信息" << std::endl;
    std::cout << "4. 查看所有图书" << std::endl;
    std::cout << "5. 查看超期图书" << std::endl;
    std::cout << "6. 封禁用户" << std::endl;
    std::cout << "7. 修改用户信息" << std::endl;
    std::cout << "8. 退出登录" << std::endl;
    std::cout << "请选择操作：";
}

/**
 * @brief 显示用户菜单
 */
void LibrarySystem::showUserMenu()
{
    std::cout << "\n=== 图书管理系统（用户模式）===" << std::endl;
    std::cout << "1. 搜索图书" << std::endl;
    std::cout << "2. 借阅图书" << std::endl;
    std::cout << "3. 归还图书" << std::endl;
    std::cout << "4. 查看已借图书" << std::endl;
    std::cout << "5. 退出登录" << std::endl;
    std::cout << "请选择操作：";
}

/**
 * @brief 推荐图书给当前用户
 */
void LibrarySystem::recommendBooks() const
{
    if (!currentUser)
        return;

    // 使用LinkList存储偏好类别和权重
    LinkList preferenceCategories; // 存储类别
    LinkList preferenceWeights;    // 存储对应权重

    // 获取用户偏好类别和权重
    for (int i = 0; i < 8; i++)
    {
        double weight = currentUser->getCategoryWeight(static_cast<BookCategory>(i));
        if (weight > 0)
        {
            preferenceCategories.addNodeToEnd(i);                           // 存储类别索引
            preferenceWeights.addNodeToEnd(static_cast<int>(weight * 100)); // 将权重转为整数存储
        }
    }

    // 存储推荐图书和分数
    LinkList recommendBooks;  // 存储图书指针转换后的整数
    LinkList recommendScores; // 存储推荐分数

    // 遍历所有图书
    for (int i = 1; i <= bookManager.getBooks().length(); i++)
    {
        Book *book = reinterpret_cast<Book *>(bookManager.getBooks().getPointer(i)->data);

        // 跳过用户已借阅过的图书
        if (currentUser->hasBorrowed(book->getBookId()))
            continue;

        // 计算推荐度
        int score = 0;
        for (int j = 1; j <= preferenceCategories.length(); j++)
        {
            if (static_cast<int>(book->getCategory()) == preferenceCategories.getPointer(j)->data)
            {
                score = (preferenceWeights.getPointer(j)->data *
                         static_cast<int>(book->getAverageRating() * 100)) /
                        100;
                break;
            }
        }

        if (score > 0)
        {
            recommendBooks.addNodeToEnd(reinterpret_cast<intptr_t>(book));
            recommendScores.addNodeToEnd(score);
        }
    }

    // 使用选择排序（因为只需要前5个）
    for (int i = 1; i <= 5 && i <= recommendScores.length(); i++)
    {
        int maxPos = i;
        for (int j = i + 1; j <= recommendScores.length(); j++)
        {
            if (recommendScores.getPointer(j)->data > recommendScores.getPointer(maxPos)->data)
            {
                maxPos = j;
            }
        }
        if (maxPos != i)
        {
            // 同时交换分数和图书指针
            recommendScores.swapNodes(i, maxPos);
            recommendBooks.swapNodes(i, maxPos);
        }
    }

    // 显示推荐结果
    for (int i = 1; i <= 5 && i <= recommendBooks.length(); i++)
    {
        Book *book = reinterpret_cast<Book *>(recommendBooks.getPointer(i)->data);
        std::cout << std::setw(10) << book->getBookId()
                  << std::setw(30) << book->getTitle()
                  << std::setw(20) << book->getAuthor()
                  << std::setw(15) << getCategoryString(book->getCategory())
                  << std::setw(10) << book->getCurrentStock() << std::endl;
    }
}

/**
 * @brief 对图书进行评分
 * @param bookId 图书ID
 * @param rating 评分(1-5)
 */
void LibrarySystem::rateBook(const std::string &bookId, int rating)
{
    if (!currentUser)
        return;

    Book *book = bookManager.findBook(bookId);
    if (book)
    {
        book->addRating(rating);
        currentUser->rateBook(bookId, rating); // 记录用户的评分历史
    }
}

/**
 * @brief 获取评分最高的图书列表
 * @param limit 返回的图书数量限制
 * @return 包含图书ID的链表
 */
LinkList LibrarySystem::getTopRatedBooks(int limit) const
{
    LinkList result;
    LinkList tempRatings; // 用于存储评分信息
    LinkList tempIds;     // 用于存储对应的书籍ID

    // 收集所有图书的评分信息
    for (int i = 1; i <= bookManager.getBooks().length(); i++)
    {
        Book *book = reinterpret_cast<Book *>(bookManager.getBooks().getPointer(i)->data);
        // 将评分乘以100转为整数存储（保留两位小数）
        tempRatings.addNodeToEnd(static_cast<int>(book->getAverageRating() * 100));
        tempIds.addNodeToEnd(std::stoi(book->getBookId()));
    }

    // 使用选择排序（因为只需要前limit个）
    for (int i = 1; i <= limit && i <= tempRatings.length(); i++)
    {
        int maxPos = i;
        for (int j = i + 1; j <= tempRatings.length(); j++)
        {
            if (tempRatings.getPointer(j)->data > tempRatings.getPointer(maxPos)->data)
            {
                maxPos = j;
            }
        }
        if (maxPos != i)
        {
            // 同时交换评分和ID
            tempRatings.swapNodes(i, maxPos);
            tempIds.swapNodes(i, maxPos);
        }
    }

    // 取前limit本书的ID
    for (int i = 1; i <= limit && i <= tempIds.length(); i++)
    {
        result.addNodeToEnd(tempIds.getPointer(i)->data);
    }

    return result;
}

/**
 * @brief 获取借阅次数最多的图书列表
 * @param limit 返回的图书数量限制
 * @return 包含图书ID的链表
 */
LinkList LibrarySystem::getMostBorrowedBooks(int limit) const
{
    LinkList result;
    LinkList tempBorrows; // 用于存储借阅次数
    LinkList tempIds;     // 用于存储对应的书籍ID

    // 收集所有图书的借阅次数
    for (int i = 1; i <= bookManager.getBooks().length(); i++)
    {
        Book *book = reinterpret_cast<Book *>(bookManager.getBooks().getPointer(i)->data);
        tempBorrows.addNodeToEnd(book->getBorrowCount());
        tempIds.addNodeToEnd(std::stoi(book->getBookId()));
    }

    // 使用选择排序
    for (int i = 1; i <= limit && i <= tempBorrows.length(); i++)
    {
        int maxPos = i;
        for (int j = i + 1; j <= tempBorrows.length(); j++)
        {
            if (tempBorrows.getPointer(j)->data > tempBorrows.getPointer(maxPos)->data)
            {
                maxPos = j;
            }
        }
        if (maxPos != i)
        {
            // 同时交换借阅次数和ID
            tempBorrows.swapNodes(i, maxPos);
            tempIds.swapNodes(i, maxPos);
        }
    }

    // 取前limit本书的ID
    for (int i = 1; i <= limit && i <= tempIds.length(); i++)
    {
        result.addNodeToEnd(tempIds.getPointer(i)->data);
    }

    return result;
}

/**
 * @brief 显示所有图书信息
 */
void LibrarySystem::displayAllBooks() const
{
    std::cout << "\n图书总览\n"
              << std::endl;
    std::cout << std::setw(10) << "ID"
              << std::setw(30) << "书名"
              << std::setw(20) << "作者"
              << std::setw(15) << "馆藏地"
              << std::setw(10) << "库存" << std::endl;
    std::cout << std::string(85, '-') << std::endl;

    bookManager.displayAllBooks();
}

/**
 * @brief 删除用户
 * @param memberId 要删除的用户ID
 * @return 删除成功返回true,失败返回false
 */
bool LibrarySystem::removeMember(const std::string &memberId)
{
    std::cout << " 开始删除用户操作" << std::endl;

    if (!isAdmin())
    {
        std::cout << " 非管理员权限" << std::endl;
        return false;
    }

    Member *member = memberManager.findMember(memberId);
    if (!member || member->getType() == MemberType::ADMIN)
    {
        std::cout << " 用户不存在或是管理员" << std::endl;
        return false;
    }

    // 删除用户的借阅记录文件
    std::string userDataFile = std::string(USER_DATA_DIR) + memberId + ".csv";
    std::cout << " 尝试删除用户数据文件: " << userDataFile << std::endl;
    std::remove(userDataFile.c_str());

    // 读取所有行并重写文件，跳过要删除的用户
    std::ifstream inFile("../data/members.csv");
    std::ofstream tempFile("../data/members_temp.csv");

    if (!inFile || !tempFile)
    {
        std::cout << " 无法打开文件" << std::endl;
        return false;
    }

    std::string line;
    bool found = false;
    while (std::getline(inFile, line))
    {
        // 检查行是否以用户ID开头
        if (line.find(memberId + ",") == 0)
        {
            found = true;
            continue; // 跳过这一行
        }
        tempFile << line << "\n";
    }

    inFile.close();
    tempFile.close();

    if (!found)
    {
        std::cout << " 在文件中未找到用户" << std::endl;
        std::remove("../data/members_temp.csv");
        return false;
    }

    // 替换原文件
    if (std::remove("../data/members.csv") != 0)
    {
        std::cout << " 删除原文件失败" << std::endl;
        return false;
    }

    if (std::rename("../data/members_temp.csv", "../data/members.csv") != 0)
    {
        std::cout << " 重命名临时文件失败" << std::endl;
        return false;
    }

    std::cout << " 文件操作完成，重新加载成员数据" << std::endl;
    memberManager.loadFromFile();
    return true;
}

/**
 * @brief 更新用户信息
 * @param userId 用户ID
 * @param newName 新用户名
 * @param newPhone 新手机号
 * @param newPassword 新密码
 * @return 更新成功返回true,失败返回false
 */
bool LibrarySystem::updateUserInfo(const std::string &userId,
                                   const std::string &newName,
                                   const std::string &newPhone,
                                   const std::string &newPassword)
{
    if (!isAdmin())
        return false;

    Member *member = memberManager.findMember(userId);
    if (!member || member->getType() == MemberType::ADMIN)
    {
        return false;
    }

    // 检查新手机号是否已被使用（如果更改了手机号）
    if (newPhone != member->getPhone())
    {
        if (memberManager.findMemberByPhone(newPhone))
        {
            return false; // 手机号已被其他用户使用
        }
    }

    // 更新用户信息
    member->updatePersonalInfo(newName, newPhone);
    if (!newPassword.empty())
    {
        member->updatePassword(newPassword);
    }

    // 保存到文件
    return memberManager.saveToFile();
}
