#!usr/bin/env python
# -*- coding:utf-8 -*-
"""
@author: dell
@file: product_filter.py
@time: 2021/03/29
@desc:
"""
import pandas as pd
import re
import numpy as np
import xlsxwriter
import pymssql


def product_washing(filepath, category, thre=1, a=0):
    conn_zi_new = pymssql.connect(host='123.56.115.207', user='zgcprice3311', password='zgcprice20200628',
                                  database='ZI_NEW', autocommit=True)
    cursor_zi_new = conn_zi_new.cursor()
    cursor_zi_new.execute(f"select col_value from data_washing_external where category_name='通用' and col_name='异常数据名称'")
    invalid_list_fetch = cursor_zi_new.fetchall()
    invalid_list = []
    for invalid_tuple in invalid_list_fetch:
        invalid_list.append(invalid_tuple[0])
    df=pd.read_excel(filepath, converters={'产品编码':str})
    df.drop(columns='Unnamed: 0', axis=1, inplace=True)
    for col in df.columns:
        df[col]=df[col].astype(str)

    cursor_zi_new.execute(f"select col_value from data_washing_external where category_name='{category}' and col_name='重复参数项'")
    other_parameters_fetch=cursor_zi_new.fetchall()
    other_parameters=[]
    for param in other_parameters_fetch:
        other_parameters.append(param[0])

    point_category_list = ['台式机', '笔记本', '一体电脑', '复印纸']
    related_product = []
    brand_grouped = df.groupby(by='产品品牌')
    for brand in brand_grouped:
        if brand[0] in invalid_list:
            continue
        tempo_dict = {}
        # 每个品牌提取产品型号关键字，放入tempo_dict
        for i in brand[1].index:
            if category in point_category_list:
                if category == '复印纸':
                    k = brand[1].loc[i, '*产品系列']
                else:
                    k = brand[1].loc[i, '*产品子系列']
                k.replace(' ','').replace('系列','').replace('_','').replace('-','').upper()
                tempo_dict[i] = [k]

            else:
                k = brand[1].loc[i, '*产品型号']
                if k in invalid_list:
                    continue
                pre_num = re.search(r'([A-Za-z]{0,4})\W?\d+', k)  # pre_num为数字前的关键字
                if pre_num:
                    pre_num = [pre_num.group(1)]
                if not pre_num:
                    pre_num = []

                num = re.search(r'(\d+)', k)  # num为数字关键字
                if num:
                    num = [num.group(1)]  # 如果连续数字超过1处，我们只提取第一处，这个可能有点问题但目前还不知道怎么办
                if not num:  # 如果没有数字，就比较英文单词
                    num = re.findall(r'[A-Za-z]+', k)

                pos_num = re.findall(
                    r'\d+([A-Za-z]+)?\W?([0-9]+)?\W?([A-Za-z]+)?\W?([0-9]+)?\W?([A-Za-z]+)?\W?([0-9]+)?\W?([A-Za-z]+)?',
                    k)  # pos_num为数字后的关键字
                if pos_num:
                    pos_num = list(pos_num[0])
                    if '升级版' in k:
                        pos_num += '升级版'
                    if '专业版' in k:
                        pos_num += '专业版'
                    if '教育版' in k:
                        pos_num += '教育版'
                    if '+' in k:
                        pos_num += '+'

                combined = pre_num + num + pos_num  # 将关键字列表合并
                while '' in combined:
                    combined.remove('')
            # pre_num = re.findall(r'^([A-Za-z]{0,4})\W?\d+', k)  # pre_num为数字前的关键字
            # if not pre_num:
            #     pre_num = re.findall(r'[\u4e00-\u9fa5]+([A-Za-z]{0,4})\W?\d+', k)
            # if not pre_num:
            #     pre_num = re.findall(r'\b([A-Za-z]{0,4})\W?\d+', k)
            # if pre_num:
            #     pre_num = [pre_num[0]]
            #
            # num = re.findall(r'\d+', k)  # num为数字关键字
            # if num:
            #     num = [num[0]]
            # pos_num = re.findall(r'\d+([A-Za-z]+)?\W?([0-9]+)?\W?([A-Za-z]+)?\W?([0-9]+)?\W?([A-Za-z]+)?\W?([0-9]+)?\W?([A-Za-z]+)?',
            #                      k)  # pos_num为数字后的关键字
            # if pos_num:
            #     pos_num = list(pos_num[0])
            #
            # combined = pre_num + num + pos_num  # 将关键字列表合并

            # # 提取品牌名关键字
            # temp_list1 = re.findall(r'([\u4e00-\u9fa5]+)', brand[0].upper())  # 提取汉字
            # while '新建品牌' in temp_list1:
            #     temp_list1.remove('新建品牌')  # 去除‘新建品牌’
            # temp_list2 = re.findall(r'[A-Za-z]+\W?[A-Za-z]+', brand[0].upper())  # 提取英文单词
            # brand_combined = temp_list1+temp_list2

                tempo_dict[i] = [set(combined)]

            other_parameters_values=[]
            for parameter in other_parameters:
                other_parameters_values.append(brand[1].loc[i,parameter])
            tempo_dict[i].extend(other_parameters_values)

        # 对比产品参数项，相同则放入related_product
        tested_product=[]
        for i in tempo_dict:
            for j in tempo_dict:
                if i != j and set([i,j]) not in tested_product:
                    count = 0
                    for index in range(1,len(tempo_dict[i])):
                        if tempo_dict[i][index]!= tempo_dict[j][index] and \
                                (tempo_dict[i][index] not in invalid_list and tempo_dict[j][index] not in invalid_list):
                            count += 1
                            break
                    if count != 0:
                        tested_product.append(set([i, j]))
                        break  # 如果出现了必须相等但不相等的参数，则退出到上一层循环。如果没有出现，则对比型号
                    if category in point_category_list:
                        if tempo_dict[i][0] == tempo_dict[j][0]:
                            related_product.append(set([i, j]))
                    else:
                        accuracy_i=0
                        accuracy_j=0
                        for word_i in tempo_dict[i][0]:
                            if word_i in tempo_dict[j][0]:
                                accuracy_i += 1/(len(tempo_dict[i][0]) + a/len(tempo_dict[i][0]))
                                accuracy_j += 1/(len(tempo_dict[j][0]) + a/len(tempo_dict[j][0]))
                        if accuracy_i >= thre or accuracy_j >= thre:
                            if not (df.loc[i,'*产品型号'].endswith('+') ^ df.loc[j,'*产品型号'].endswith('+')):
                                related_product.append(set([i,j]))
                    tested_product.append(set([i,j]))

            # a = set([i])
            # for j in tempo_dict:
            #     if tempo_dict[i] == tempo_dict[j]:
            #         a.add(j)
            # if len(a) > 1:
            #     related_product.append(a)
        # for i in tempo_dict:
        #     for j in tempo_dict:
        #         if i != j:
        #             if tempo_dict[i] == tempo_dict[j]:
        #                 related_product.append(set([i, j]))

    # # 这一步为去重
    # product_unique=[]
    # for item in related_product:
    #     if item not in product_unique:
    #         product_unique.append(item)

    # 将数据导出到excel表格。重复的产品数据两两并列 和其他的重复数据组中间空一行
    workbook = xlsxwriter.Workbook('./product_filter.xlsx')
    bold_format = workbook.add_format({'bold': True})
    worksheet = workbook.add_worksheet()
    col = 0
    row = 0
    worksheet.write_string(row, col, 'Index', bold_format)
    col += 1
    for column in df.columns:
        worksheet.write_string(row, col, column, bold_format)
        col += 1
    worksheet.write_string(row, col, '正确产品编码', bold_format)
    col += 1
    worksheet.write_string(row, col, '正确产品名称', bold_format)
    row = 1
    col = 0
    for item in related_product:
        for inner_item in item:
            worksheet.write_string(row, col, str(inner_item))
            for value in df.loc[inner_item].values:
                col += 1
                worksheet.write_string(row, col, value)
            col = 0
            row += 1
        row += 1

    workbook.close()


if __name__ == '__main__':
    filepath = "E:\\ZDZC\\Sourcetree_local\\公共代码\\一体电脑参数确认.xlsx"
    category = '一体电脑'
    product_washing(filepath,category)
