#pragma once
#include <fstream>
#include <string>
#include <cstring>
#include <vector>
#include <SDL.h>
#include <algorithm>
#include "Tool/Tool_String.h"

typedef unsigned char BYTE;

// 定义宏用于注册获取不同类型值的函数
#define REGISTER_GET_FUNCTION(Type, FunctionName)   \
    Type Get##FunctionName()                        \
    {                                               \
        char buffer[sizeof(Type)];                  \
        read(buffer, sizeof(Type));                 \
        Type result;                                \
        std::memcpy(&result, buffer, sizeof(Type)); \
        return result;                              \
    }
class Ifstream_PVF
{
public:
    // 使用vector存储数据，替代char*
    std::vector<char> _Data;
    // 当前位置
    int _CurPos = 0;
    // 上一次读取的实际大小
    int _LastReadSize = 0;

public:
    Ifstream_PVF(std::string fileName);
    ~Ifstream_PVF();

public:
    int tellg()
    {
        return _CurPos;
    }

    // 获取数据大小
    int size() const
    {
        return static_cast<int>(_Data.size());
    }

    void read(char *ptr, int size)
    {
        // 使用vector的size()作为最大长度
        if ((size + _CurPos) > static_cast<int>(_Data.size()))
        {
            size = static_cast<int>(_Data.size()) - _CurPos;
        }
        memcpy(ptr, _Data.data() + _CurPos, size);
        _CurPos += size;
        _LastReadSize = size;
    }

    int gcount()
    {
        return _LastReadSize;
    }

    void seek(int _jidx)
    {
        // 确保不会越界
        _CurPos = std::clamp(_jidx, 0, static_cast<int>(_Data.size()));
    }

public:
    unsigned int charPtrToInt(const char *bytes)
    {
        unsigned int result;
        std::memcpy(&result, bytes, sizeof(int));
        return result;
    }

    void CrcDecode(const int Length, const int crc32)
    {
        int num = 0x81A79011;
        int originalPos = tellg(); // 保存初始位置
        for (int i = 0; i < Length; i += 4)
        {
            int Pos = tellg();
            char buffer[4];
            read(buffer, 4);
            unsigned int anInt = charPtrToInt(buffer);
            unsigned int val = (anInt ^ num ^ crc32);
            unsigned int jiemi = (val >> 6) | ((val << (32 - 6)) & 0xFFFFFFFF);

            // 使用vector的data()获取数据指针
            if (Pos + 3 < static_cast<int>(_Data.size()))
            {
                _Data[Pos] = ((jiemi >> 0) & 0xFF);
                _Data[Pos + 1] = ((jiemi >> 8) & 0xFF);
                _Data[Pos + 2] = ((jiemi >> 16) & 0xFF);
                _Data[Pos + 3] = ((jiemi >> 24) & 0xFF);
            }
        }
        // 重置读取位置，因为解码过程中移动了指针
        seek(originalPos + Length); // 移动到解码后的位置
    }

    std::string tolower(std::string str)
    {
        for (size_t i = 0; i < str.length(); ++i)
        {
            str[i] = std::tolower(str[i]);
        }
        return str;
    }

    std::vector<std::string> split(const std::string &str, const std::string &delimiter)
    {
        std::vector<std::string> tokens;
        size_t pos = 0;
        size_t found;
        while ((found = str.find(delimiter, pos)) != std::string::npos)
        {
            tokens.push_back(str.substr(pos, found - pos));
            pos = found + delimiter.length();
        }
        tokens.push_back(str.substr(pos));
        return tokens;
    }

public:
    REGISTER_GET_FUNCTION(int, Int);
    REGISTER_GET_FUNCTION(short, Short);
    REGISTER_GET_FUNCTION(unsigned short, UShort);

    std::string GetString(const int size)
    {
        if (size <= 0)
            return "";

        // 确保不会读取超出范围的数据
        int readSize = std::min(size, static_cast<int>(_Data.size()) - _CurPos);
        std::string result(_Data.data() + _CurPos, readSize);
        _CurPos += readSize;
        _LastReadSize = readSize;

        if (readSize != size)
        {
            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "未能成功读取指定字节数的数据！");
        }

        return (result);
    }

    std::string GetStringNormal(const int size)
    {
        // 与GetString实现相同，可根据实际需求区分
        if (size <= 0)
            return "";

        int readSize = std::min(size, static_cast<int>(_Data.size()) - _CurPos);
        std::string result(_Data.data() + _CurPos, readSize);
        _CurPos += readSize;
        _LastReadSize = readSize;

        if (readSize != size)
        {
            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "未能成功读取指定字节数的数据！");
        }

        return result;
    }
};
