import xlsxwriter
import pandas as pd
import os

class excel_format:

    """
    Excel Format class help to create customized format excel file.
    """
    def __init__(self, csv_name,path=os.getcwd()):
        self.csv_name = csv_name
        self.path = path
        self.convert_csv_to_xlsx()

    def convert_csv_to_xlsx(self):
        """
        This function will take the data from CSV file in the folder
        Converting CSV file into a data frame
        Return workbook and worksheet for further manipulation

        """
        self.data_frame=pd.read_csv(self.csv_name, encoding='utf-8')
        self.row_length,self.column_length=self.data_frame.shape
        writer=pd.ExcelWriter(os.path.join(self.path,self.csv_name.replace('.csv','.xlsx')),engine="xlsxwriter")
        self.data_frame.to_excel(writer,index=False,sheet_name="Sheet1")
        workbook=writer.book
        worksheet=writer.sheets['Sheet1']
        self.workbook=workbook
        self.worksheet=worksheet

    def row_rotation(self,row,angle):
        """
        This function will rotate the row.
        :param row: Row Index Represent in Int
        :param angle: The degree that you want to rotate. Takes in Int
        :return:
        """
        if row==0:
            row_data=self.data_frame.columns.tolist()
            row_data = [str(data).replace("nan", "") for data in row_data]
        else:
            row_data = self.data_frame.iloc[row].tolist()
            row_data = [str(data).replace("nan", "") for data in row_data]
        format=self.workbook.add_format()
        format.set_rotation(angle)

        tuple_row_data=tuple(row_data)



        self.worksheet.write_row(0,0,tuple_row_data,format)
    def row_format(self,row, height,format=None):

        """
        This function provides custom format for the entire row.

        :param row:  Integer
        :param height: Integer
        :param format: workbook Format
        :return:
        """
        if format!=None:

            format=self.workbook.add_format(format)
        self.worksheet.set_row(row,height,format)
    def freeze_panel(self,column,row):
        """
        This will freeze the pannel
        :param column: Int
        :param row: Int
        :return:
        """
        self.worksheet.freeze_panes(column,row)
    def autofilter_whole_sheet(self):
        """
        Run this function will create a filter for the whole sheet
        :return:
        """

        self.worksheet.autofilter(0,0,self.row_length,self.column_length-1)

    def get_column_index(self,column_name):
        """
        This function return the index given column name
        :param column_name: String
        :return: Integer
        """
        column_names = self.data_frame.columns.tolist()
        index = None

        for inde, name in enumerate(column_names):
            if name == column_name:
                index = inde
        return int(index)
    def condition_format_column(self, column_name,formats=None):
        """
        This provides conditional formatting for column
        :param column_name: String
        :param formats: Workbook Format
        :return:
        """
        index=self.get_column_index(column_name)


        for format in formats:

            self.worksheet.conditional_format(1,index,self.row_length,index,format)
    def num_format(self,column_name,format=None):
        """
        This function provides formatting for number

        :param column_name: String
        :param format: Work book format
        :return:
        """
        json_format={
            'num_format':f"{format}"
        }
        format=self.workbook.add_format(json_format)
        index=self.get_column_index(column_name)
        self.worksheet.set_column(index,index,None, format)
    def set_column_width(self,column_name,column_width):
        """
        This function sets up the width column.
        :param column_name: String

        :param column_width: Integer
        :return:
        """
        index=self.get_column_index(column_name)
        self.worksheet.set_column(index,index,column_width)
    def column_width_auto_size(self,column_name):
        """
        This function will automatically adjust your columns width size
        :param column_name: String
        :return:
        """
        data=self.data_frame[column_name].tolist()
        data.append(column_name)

        data=[str(i).replace("nan",",") for i in data]

        len_list=[len(str(i)) for i in data]

        max_len=max(len_list)

        character_value=data[len_list.index(max_len)]

        lower_case_char=0
        uper_case_char=0
        for char in character_value:
            if char.isupper():
                uper_case_char+=1
            else:
                lower_case_char+=1


        index=self.get_column_index(column_name)
        pixl_value=(90/10)*uper_case_char+(80/10)*lower_case_char
        self.worksheet.set_column_pixels(index,index,pixl_value)
    def column_data_validation(self,column_name,list):
        """
        This functions provides Excel Validation given list and column name
        :param column_name: String
        :param list: List
        :return:
        """
        validation_json={
            'validate':'list',
            'source':list
        }
        index=self.get_column_index(column_name)
        self.worksheet.data_validation(1,index,self.row_length,index,validation_json)

    def no_repeat(self,list):
        """
        This functions remove repeated items in a list
        :param list: list
        :return:
        """
        no_repeated_list=[]
        for item in list:
            if item not in no_repeated_list:
                no_repeated_list.append(item)
        return no_repeated_list

    def get_category(self,column_name):
        """
        This function will return set of category in a column with no repeated value
        :param column_name:String
        :return: List
        """

        category_list=self.data_frame[column_name].tolist()
        return self.no_repeat(category_list)
    def category_color_format_generator(self,item_list,color_list,string=True):
        """
        This functions generating a json data for workbook formatting given Item List and Color List
        :param item_list:List
        :param color_list: List
        :param string: Optional whether data is string or int
        :return: Json Object. Workbook Formatting
        """
        format_array=[]
        zip_list=zip(item_list,color_list)
        for item,color in zip_list:
            color_format=self.workbook.add_format({"bg_color":color})
            if string==True:

                json_format={
                    "type":"cell",
                    "criteria":"equal to",
                    "value":f"\"{item}\"",
                    "format":color_format
                }
            else:
                json_format = {
                    "type": "cell",
                    "criteria": "equal to",
                    "value": f"{item}",
                    "format": color_format
                }
            format_array.append(json_format)
        return format_array







    # def combine(self):
    #     formatD={'type': '3_color_scale',
    #                                  'min_color': "red",
    #                                  'mid_color': "yellow",
    #                                  'max_color': "green"}
    #     formats=[formatD]
    #     grey=self.workbook.add_format({'bg_color':'red'})
    #     formatA={'type': 'cell',
    #                 'criteria':'equal to',
    #                 'value': '"TERM_OF_INTEREST"',
    #                 'format':grey
    #              }
    #     formats1=[formatA]
    #     contitional_format={'type':'3_color_scale','min_color': '#C5D9F1',
    #                                     'max_color': '#538ED5'}
    #
    #     self.condition_format_column("frequency_percentile",formats)
    #     self.condition_format_column("system_asserted_tag", formats1)
    #     self.freeze_panel(1,1)
    #     self.row_format(1,50)
    #     self.row_rotation(0,30)
    #     self.autofilter_whole_sheet()
    #     self.workbook.close()








"""
needed function documentation
set_column()
set_rotation(angle)
worksheet.set_row()
"""



