import { Injectable } from '@angular/core';
import * as _ from 'lodash';
import { CloudObject, CloudQuery, CloudUser } from '../ncloud';

@Injectable({
    providedIn: 'root'
})
export class RecommendationService {
    userPrefer: CloudObject | any; // 用户偏好数据
    itemTags: CloudObject | any; // 物品标签数据
    // relatedTags: any;// 相关物品标签数据

    constructor() { }

    // 用户点击物品
    public async onItemClick(currentUser: CloudUser, item: CloudObject) {
        console.log("用户点击物品: ");
        console.log(item);

        // 获取用户偏好
        let query = new CloudQuery("UserPrefer");
        query.include("ItemID");
        query.equalTo("UserID", currentUser.toPointer());
        query.equalTo("ItemID", item.toPointer());
        this.userPrefer = await query.find();
        console.log("获取用户偏好: ");
        console.log(this.userPrefer[0]);

        const clickIncrement = 1; // 点击增加的偏好值
        const relatedIncrementFactor = 0.5; // 相关物品增加偏好值的因子

        //更新点击物品的偏好值
        if (this.userPrefer[0]?.id) {
            console.log("获取该物品偏好值：" + this.userPrefer[0].data['preference']);
            this.userPrefer[0].data['preference'] += clickIncrement; // 每次点击增加偏好值
            console.log("点击后的偏好值：" + this.userPrefer[0].data['preference']);
        } else {
            let newUserPrefer = new CloudObject("UserPrefer");
            newUserPrefer.set({ "UserID": currentUser.toPointer(), "ItemID": item.toPointer(), "preference": clickIncrement });
            console.log("用户即将保存数据: ");
            console.log(newUserPrefer);
            await newUserPrefer.save() // 如果没有记录，添加新记录
            this.userPrefer[0] = newUserPrefer; // 同时更新本地用户偏好对象
        }

        // 获取点击物品的标签
        this.itemTags = this.userPrefer[0].data['ItemID'].tag;
        console.log("获取点击物品标签: ")
        console.log(this.itemTags);

        //更新与点击物品相关的其他物品的偏好值
        query = new CloudQuery("ItemInfo");
        let relatedObject = await query.find();
        for (let i = 0; i < relatedObject.length; i++) {
            if (this.userPrefer[0].data['ItemID'].objectId != relatedObject[i].get('objectId') && relatedObject[i].get('tag').length != 0) {
                const similarity = this.calculateTagSimilarity(this.userPrefer[0].data['ItemID'].tag, relatedObject[i].get('tag'));
                console.log(this.userPrefer[0].data['ItemID'].tag + "与" + relatedObject[i].get('tag') + "的相似度为:" + similarity);
                if (similarity > 0) {
                    const relatedPreferenceIncrement = clickIncrement * relatedIncrementFactor * similarity;
                    let relatedUserPrefer: CloudObject | any;
                    // 查找相关物品的用户偏好数据
                    let relatedUserQuery = new CloudQuery("UserPrefer");
                    relatedUserQuery.include("ItemID");
                    relatedUserQuery.equalTo("UserID", currentUser.toPointer());
                    relatedUserQuery.equalTo("ItemID", relatedObject[i].toPointer());
                    relatedUserPrefer = await relatedUserQuery.find();
                    console.log("查找到相关物品的用户偏好数据: ");
                    console.log(relatedUserPrefer[0]);
                    if (relatedUserPrefer.length > 0) {
                        const userPrefer = relatedUserPrefer[0]; // 获取第一个用户偏好对象
                        console.log("查找到相关物品的用户偏好数据，准备做修改: ");
                        console.log("修改前偏好值: " + userPrefer.get('preference'));
                        // 直接更新偏好值
                        const updatedPreference = parseFloat(userPrefer.get('preference')) + relatedPreferenceIncrement;
                        userPrefer.set({"preference": updatedPreference, "ItemID": relatedObject[i].toPointer() , "UserID": currentUser.toPointer() });
                        // 保存更新后的偏好值
                        await userPrefer.save();
                        console.log("修改后偏好值: " + updatedPreference);
                    } else {
                        console.log("查找不到相关物品的用户偏好数据，准备做添加: ");
                        let newRelatedUserPrefer = new CloudObject("UserPrefer");
                        newRelatedUserPrefer.set({ "UserID": currentUser.toPointer(), "ItemID": relatedObject[i].toPointer(), "preference": relatedPreferenceIncrement });
                        await newRelatedUserPrefer.save() // 如果没有记录，添加新记录
                        relatedUserPrefer[0] = newRelatedUserPrefer; // 同时更新本地用户偏好对象
                        console.log("已添加，相似度：" + relatedUserPrefer[0].data['preference']);
                    }

                }

            }
        }
    }


    //     // 获取物品的标签
    //     private getItemTags(itemID: number) {
    //         const item = this.itemTags.find(it => it.ItemID === itemID);
    //         return item ? item.Tags : [];
    //     }

    //     // 获取用户的偏好
    //     private getUserPreferences(userID: string) {
    //         return this.userPreferences.filter(pref => pref.UserID === userID);
    //     }

    // 计算标签相似度
    private calculateTagSimilarity(tagsA: string[], tagsB: string[]): number {
        const intersection = _.intersection(tagsA, tagsB).length;
        const union = _.union(tagsA, tagsB).length;
        return union === 0 ? 0 : intersection / union; // Jaccard 相似度
    }

    //     // 获取推荐物品
    //     public getRecommendations(userID: string): number[] {
    //         const userPrefs = this.getUserPreferences(userID);
    //         const recommendedItems: { [key: number]: number } = {}; // 物品ID和推荐分数

    //         userPrefs.forEach(userPref => {
    //             const itemTags = this.getItemTags(userPref.ItemID);

    //             this.itemTags.forEach(item => {
    //                 if (item.ItemID !== userPref.ItemID) {
    //                     const similarity = this.calculateTagSimilarity(itemTags, item.Tags);
    //                     if (similarity > 0) {
    //                         if (!recommendedItems[item.ItemID]) {
    //                             recommendedItems[item.ItemID] = 0;
    //                         }
    //                         // 根据用户的偏好和标签相似度计算推荐分数
    //                         recommendedItems[item.ItemID] += userPref.Preference * similarity;
    //                     }
    //                 }
    //             });
    //         });

    //         // 返回推荐物品按分数排序
    //         return Object.entries(recommendedItems)
    //             .sort((a, b) => b[1] - a[1]) // 按照分数降序排序
    //             .map(([itemID]) => Number(itemID)); // 返回物品ID数组
    //     }
}
