// CloudObject.ts

let serverURL = `https://dev.fmode.cn/parse`;
if (location.protocol == "http://127.0.0.1:4040/apps") {
    //serverURL = `http://dev.fmode.cn:1337/parse`;
    serverURL = `http://dev.fmode.cn:1337/parse`;
}

export class CloudObject {
    className: string;
    id: string | undefined = undefined;
    createdAt: any;
    updatedAt: any;
    data: Record<string, any> = {};

    constructor(className: string) {
        this.className = className;
    }

    toPointer() {
        return { "__type": "Pointer", "className": this.className, "objectId": this.id };
    }

    set(json: Record<string, any>) {
        Object.keys(json).forEach(key => {
            if (["objectId", "id", "createdAt", "updatedAt"].indexOf(key) > -1) {
                return;
            }
            this.data[key] = json[key];
        });
    }

    get(key: string) {
        return this.data[key] || null;
    }

    async save() {
        let method = "POST";
        let url = serverURL + `/classes/${this.className}`;

        // 更新
        if (this.id) {
            url += `/${this.id}`;
            method = "PUT";
        }

        const body = JSON.stringify(this.data);
        const response = await fetch(url, {
            headers: {
                "content-type": "application/json;charset=UTF-8",
                "x-parse-application-id": "dev"
            },
            body: body,
            method: method,
            mode: "cors",
            credentials: "omit"
        });

        const result = await response?.json();
        if (result?.error) {
            console.error(result?.error);
        }
        if (result?.objectId) {
            this.id = result?.objectId;
        }
        return this;
    }

    async destroy() {
        if (!this.id) return;
        const response = await fetch(serverURL + `/classes/${this.className}/${this.id}`, {
            headers: {
                "x-parse-application-id": "dev"
            },
            body: null,
            method: "DELETE",
            mode: "cors",
            credentials: "omit"
        });

        const result = await response?.json();
        if (result) {
            this.id = undefined;
        }
        return true;
    }
}

// CloudQuery.ts
export class CloudQuery {
    className: string;
    queryParams: Record<string, any> = { where: {} };

    constructor(className: string) {
        this.className = className;
    }

    include(...fileds: string[]) {
        this.queryParams["include"] = fileds;
    }
    greaterThan(key: string, value: any) {
        if (!this.queryParams["where"][key]) this.queryParams["where"][key] = {};
        this.queryParams["where"][key]["$gt"] = value;
    }

    greaterThanAndEqualTo(key: string, value: any) {
        if (!this.queryParams["where"][key]) this.queryParams["where"][key] = {};
        this.queryParams["where"][key]["$gte"] = value;
    }

    lessThan(key: string, value: any) {
        if (!this.queryParams["where"][key]) this.queryParams["where"][key] = {};
        this.queryParams["where"][key]["$lt"] = value;
    }

    lessThanAndEqualTo(key: string, value: any) {
        if (!this.queryParams["where"][key]) this.queryParams["where"][key] = {};
        this.queryParams["where"][key]["$lte"] = value;
    }

    equalTo(key: string, value: any) {
        if (!this.queryParams["where"]) this.queryParams["where"] = {};
        this.queryParams["where"][key] = value;
    }

    async get(id: string) {
        const url = serverURL + `/classes/${this.className}/${id}?`;

        const response = await fetch(url, {
            headers: {
                "if-none-match": "W/\"1f0-ghxH2EwTk6Blz0g89ivf2adBDKY\"",
                "x-parse-application-id": "dev"
            },
            body: null,
            method: "GET",
            mode: "cors",
            credentials: "omit"
        });

        const json = await response?.json();
        if (json) {
            let existsObject = this.dataToObj(json)
            return existsObject;
        }
        return null
    }

    async find(): Promise<Array<CloudObject>> {
        let url = serverURL + `/classes/${this.className}?`;

        let queryStr = ``
        Object.keys(this.queryParams).forEach(key => {
            let paramStr = JSON.stringify(this.queryParams[key]);
            if (key == "include") {
                paramStr = this.queryParams[key]?.join(",")
            }
            if (queryStr) {
                url += `${key}=${paramStr}`;
            } else {
                url += `&${key}=${paramStr}`;
            }
        })
        // if (Object.keys(this.queryParams["where"]).length) {

        // }

        const response = await fetch(url, {
            headers: {
                "if-none-match": "W/\"1f0-ghxH2EwTk6Blz0g89ivf2adBDKY\"",
                "x-parse-application-id": "dev"
            },
            body: null,
            method: "GET",
            mode: "cors",
            credentials: "omit"
        });

        const json = await response?.json();
        let list = json?.results || []
        let objList = list.map((item: any) => this.dataToObj(item))
        return objList || [];
    }


    async first() {
        let url = serverURL + `/classes/${this.className}?`;

        if (Object.keys(this.queryParams["where"]).length) {
            const whereStr = JSON.stringify(this.queryParams["where"]);
            url += `where=${whereStr}&limit=1`;
        }

        const response = await fetch(url, {
            headers: {
                "if-none-match": "W/\"1f0-ghxH2EwTk6Blz0g89ivf2adBDKY\"",
                "x-parse-application-id": "dev"
            },
            body: null,
            method: "GET",
            mode: "cors",
            credentials: "omit"
        });

        const json = await response?.json();
        const exists = json?.results?.[0] || null;
        if (exists) {
            let existsObject = this.dataToObj(exists)
            return existsObject;
        }
        return null
    }

    dataToObj(exists: any): CloudObject {
        let existsObject = new CloudObject(this.className);
        Object.keys(exists).forEach(key => {
            if (exists[key]?.__type == "Object") {
                exists[key] = this.dataToObj(exists[key])
            }
        })
        existsObject.set(exists);
        existsObject.id = exists.objectId;
        existsObject.createdAt = exists.createdAt;
        existsObject.updatedAt = exists.updatedAt;
        return existsObject;
    }
}

// CloudUser.ts
export class CloudUser extends CloudObject {
    constructor() {
        super("UserTravel"); // 假设用户类在Parse中是"UserTravel"
        // 读取用户缓存信息
        let userCacheStr = localStorage.getItem("NCloud/dev/User")
        if (userCacheStr) {
            let userData = JSON.parse(userCacheStr)
            // 设置用户信息
            this.id = userData?.objectId;
            this.sessionToken = userData?.sessionToken;
            this.data = userData; // 保存用户数据
        }
    }

    sessionToken: string | null = ""
    /** 获取当前用户信息 */
    async current() {
        if (!this.sessionToken || !this.id) {
            console.error("用户未登录");
            return null;
        }
        // 可选：查询 UserTravel 表验证用户是否存在（增强安全性）
        const query = new CloudQuery("UserTravel");
        const user = await query.get(this.id);
        if (user) return this;
        else {
            this.clearUserCache(); // 缓存无效时清除
            return null;
        }
        // const response = await fetch(serverURL + `/users/me`, {
        //     headers: {
        //         "x-parse-application-id": "dev",
        //         "x-parse-session-token": this.sessionToken // 使用sessionToken进行身份验证
        //     },
        //     method: "GET"
        // });

        // const result = await response?.json();
        // if (result?.error) {
        //     console.error(result?.error);
        //     return null;
        // }
        // return result;
    }

    /** 登录 */
    // CloudUser.ts
async login(identifier: string, password: string): Promise<CloudUser | null> {
        try {
            // 使用$or查询优化登录
            const query = new CloudQuery(this.className);
            query.queryParams["where"] = {
                $or: [
                    { username: identifier },
                    { email: identifier },
                    { phone: identifier }
                ]
            };

            const users = await query.find();
            
            // 精确匹配用户
            const user = users.find(u => {
                // 安全密码验证（实际应使用哈希比较）
                return u.get('password') === password;
            });

            if (user) {
                // 设置当前用户信息
                this.id = user.id;
                this.set(user.data);
                
                // 生成安全的sessionToken
                this.sessionToken = this.generateSessionToken();
                
                // 保存到本地存储
                localStorage.setItem("NCloud/dev/User", JSON.stringify({
                    ...this.data,
                    objectId: this.id,
                    sessionToken: this.sessionToken
                }));
                
                return this;
            }
            return null;
        } catch (error) {
            console.error('登录失败:', error);
            throw new Error('登录失败，请检查凭证');
        }
    }

    /** 生成安全的sessionToken */
    private generateSessionToken(): string {
        const array = new Uint32Array(10);
        crypto.getRandomValues(array);
        return Array.from(array, dec => dec.toString(16).padStart(8, '0')).join('');
    }

    /** 登出 */
    async logout(): Promise<boolean> {
  try {
    localStorage.removeItem("NCloud/dev/User");
    this.id = undefined;
    this.sessionToken = null;
    this.data = {};
    return true;
  } catch (error) {
    console.error('登出失败:', error);
    throw error;
  }
}

clearUserCache() {
    this.id = undefined;
    this.sessionToken = null;
    this.data = {};
    localStorage.removeItem("NCloud/dev/User");
}

    /** 注册 */
    // CloudUser.ts
async signUp(username: string, password: string, additionalData: Record<string, any> = {}): Promise<CloudUser | null> {
    try {
        // 检查用户名是否已存在
        const usernameQuery = new CloudQuery(this.className);
        usernameQuery.equalTo("username", username);
        const existingUsers = await usernameQuery.find();
        
        if (existingUsers.length > 0) {
            throw new Error('用户名已被使用');
        }
        
        // 检查邮箱是否已存在
        if (additionalData["email"]) {
            const emailQuery = new CloudQuery(this.className);
            emailQuery.equalTo("email", additionalData["email"]);
            const existingEmails = await emailQuery.find();
            
            if (existingEmails.length > 0) {
                throw new Error('邮箱已被注册');
            }
        }
        
        // 检查手机号是否已存在
        if (additionalData["phone"]) {
            const phoneQuery = new CloudQuery(this.className);
            phoneQuery.equalTo("phone", additionalData["phone"]);
            const existingPhones = await phoneQuery.find();
            
            if (existingPhones.length > 0) {
                throw new Error('手机号已被注册');
            }
        }

        // 创建新用户
        const userObj = new CloudObject(this.className);
        userObj.set({
            username,
            password,
            ...additionalData,
            createdAt: new Date(),
            updatedAt: new Date()
        });
        
        const savedUser = await userObj.save();
        
        // 设置当前用户信息
        this.id = savedUser.id;
        this.set(savedUser.data);
        this.sessionToken = `session_${Date.now()}`;
        
        // 保存到本地存储
        localStorage.setItem("NCloud/dev/User", JSON.stringify({
            ...this.data,
            objectId: this.id,
            sessionToken: this.sessionToken
        }));
        
        // 注册后自动登录
        return await this.login(username, password);

    } catch (error) {
        console.error('注册失败:', error);
        throw error;
    } finally {
        // 可选：清理操作
    }
}

    override async save() {
        let method = "POST";
        let url = serverURL + `/users`;

        // 更新用户信息
        if (this.id) {
            url += `/${this.id}`;
            method = "PUT";
        }

        let data: any = JSON.parse(JSON.stringify(this.data))
        delete data.createdAt
        delete data.updatedAt
        delete data.ACL
        delete data.objectId
        const body = JSON.stringify(data);
        let headersOptions: any = {
            "content-type": "application/json;charset=UTF-8",
            "x-parse-application-id": "dev",
            "x-parse-session-token": this.sessionToken, // 添加sessionToken以进行身份验证
        }
        const response = await fetch(url, {
            headers: headersOptions,
            body: body,
            method: method,
            mode: "cors",
            credentials: "omit"
        });

        const result = await response?.json();
        if (result?.error) {
            console.error(result?.error);
        }
        if (result?.objectId) {
            this.id = result?.objectId;
        }
        localStorage.setItem("NCloud/dev/User", JSON.stringify(this.data))
        return this;
    }
}

export class CloudApi {
    async fetch(path: string, body: any, options?: {
        method: string
        body: any
    }) {

        let reqOpts: any = {
            headers: {
                "x-parse-application-id": "dev",
                "Content-Type": "application/json"
            },
            method: options?.method || "POST",
            mode: "cors",
            credentials: "omit"
        }
        if (body || options?.body) {
            reqOpts.body = JSON.stringify(body || options?.body);
            reqOpts.json = true;
        }
        let host = `https://dev.fmode.cn`
        // host = `http://127.0.0.1:1337`
        let url = `${host}/api/` + path
        console.log(url, reqOpts)
        const response = await fetch(url, reqOpts);
        let json = await response.json();
        return json
    }
}