#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''
@filename     : ShopScore.py
@description     : 品规-商户-评分矩阵：品规(用户)对商铺(物品)的评分矩阵，将结果保存在score.csv文件中
@time     : 2025/01/31/02
@author     : Sherlock1011 & Min1027
@Version     : 1.0
'''


from database import MySqlDao
from decimal import Decimal

# 算法封装成一个类
class UserItemScore:
    """TODO 1. 将结果保存到redis数据库中"""
    def __init__(self):
        self.weights = {
            "MONTH6_SALE_QTY": Decimal(0.1),
            "MONTH6_SALE_AMT": Decimal(0.1),
            "MONTH6_GROSS_PROFIT_RATE": Decimal(0.03),
            "MONTH6_SALE_QTY_YOY": Decimal(0.1),
            "MONTH6_SALE_QTY_MOM": Decimal(0.1),
            "MONTH6_SALE_AMT_YOY": Decimal(0.1),
            "MONTH6_SALE_AMT_MOM": Decimal(0.1),
            "ORDER_FULLORDR_RATE": Decimal(0.1),
            "CUSTOMER_REPURCHASE_RATE": Decimal(0.1),
            "NEW_PRODUCT_ORDER_QTY_OCC": Decimal(0.03),
            "LISTING_RATE": Decimal(0.1),
            "OUT_STOCK_DAYS": Decimal(0.02),
            "RETAIL_PRICE_INDEX": Decimal(0.02)
        }
        self.dao = MySqlDao()

    # 均值方差归一化函数
    def standardize_column(self, column):
        if(column.max() == column.min() and column.max() == 0):
            return 0
        elif (column.max() == column.min() and column.max() != 0):
            return 1
        else:
            return (column - column.min()) / (column.max() - column.min())

    # 按照品规分组归一化并计算评分
    def calculate_heart_per_product(self, group):
        for column in self.weights.keys():
            if column == "OUT_STOCK_DAYS":
                group[column] = 1 - self.standardize_column(group[column])
            else:
                group[column] = self.standardize_column(group[column])
        group["SCORE"] = group.apply(
            lambda row: sum(Decimal(row[col]) * weight for col, weight in self.weights.items()) * 100, axis=1
        )
        return group

    # 主算法函数：计算品规-商铺评分矩阵
    def score(self, order_data):
       

        # 应用分组计算
        df_result = order_data.groupby("PRODUCT_CODE").apply(self.calculate_heart_per_product).reset_index(drop=True)
        df_result = df_result.sort_values(by=["PRODUCT_CODE", "SCORE"], ascending=[True, False])

        # 选择要保存的列
        return df_result[['PRODUCT_CODE', 'BB_RETAIL_CUSTOMER_CODE', 'SCORE']]
 
if __name__ == "__main__":
    # 创建一个 ItemCF 类的实例
    item_cf_algorithm = UserItemScore()
    dao = MySqlDao()
    # 读取数据
    order_data = dao.load_order_data()

    # 调用算法
    scores = item_cf_algorithm.score(order_data)
    
    scores_path = "./models/recall/itemCF/matrix/score.csv"
    
    # 保存评分结果到csv文件
    scores.to_csv(scores_path, index=False, encoding="utf-8")
    