import pandas as pd
import numpy as np
import math
import sys
import re
from scipy.stats import rankdata
from argparse import ArgumentParser
from collections import Counter

def main():    
    if len(sys.argv) >= 4:
        file = sys.argv[1]
        weights = list(map(float, sys.argv[2].strip().split(',')))
        impacts = list(sys.argv[3].strip().split(','))
        assert "csv" in f"{file}", "Could not recognize csv file, try checking your input file"
        data = pd.read_csv(file).iloc[:, 1:]
        if len(sys.argv) == 5:
            opfile = sys.argv[4]
            calc(data , weights , impacts, opfile)
        else:
            opfile = "101903150-result"
            calc(data , weights , impacts, opfile)
    else:
        print("PUT ARGUMENTS IN ORDER : python -m topsis.topsis <InputDataFile> <Weights> <Impacts> <ResultFileName>")
    print(data)
    
    
    
def calc(data , weights , impacts, opfile):
    n,m=data.shape
    df=data.iloc[:,1:]
    x=df.values.tolist()
    for j in range(0,len(x[0])):
        sumsq=0
        for i in range(0,n):
            sumsq+=x[i][j]**2
        sumsq=sumsq**0.5
        for i in range(0,len(x)):
            x[i][j]/=sumsq   
    #print(x)
    
    weight = list(weights)      
    # for i in range(1,len(x)):
    #     for j in range(1,len(x[0])):
    #         x[i][j]*=weight[i]
    mat = np.array(x, dtype = np.float64)
    col = len(mat[0])
    row = len(mat)
    # n_mat = np.array([[0]*col for _ in range(row)], dtype = np.float64)
    # for i in range(col):
    #     temp = np.sum(mat[:, i]**2)**0.5
    #     n_mat[:, i] = mat[:, i] / temp
    w_mat = np.array([[0]*col for _ in range(row)], dtype = np.float64)
    for i in range(col):
            w_mat[:, i] = mat[:, i] * weights[i]
    best = np.array([0]*col, dtype = np.float64)
    worst = np.array([0]*col, dtype = np.float64)
    mat=w_mat
    for i in range(col):
        best[i] = np.max(mat[:, i])
        worst[i] = np.min(mat[:, i])
        if impacts[i] == "-":
            best[i],worst[i] = worst[i],best[i]    

    from_best = np.array([0]*row, dtype = np.float64)
    from_worst = np.array([0]*row, dtype = np.float64)
    pfm = np.array([0]*row, dtype = np.float64)
    ranks = np.array([0]*row, dtype = np.float64)
    for i in range(row):
        from_best[i] = np.sum((mat[i, :] - best)**2)**0.5
        from_worst[i] = np.sum((mat[i, :] - worst)**2)**0.5
        pfm = from_worst/(from_best + from_worst)
    pfm = pfm.tolist()
    ranks = len(pfm)-rankdata(pfm).astype(int)+1

    data['Topsis Score']=pfm
    data['Rank']=ranks
    data.to_csv(f'{opfile}',index=False)
        

if __name__ == "__main__":
    main()