# /user/bin/env python3
# -*- coding: utf-8 -*-
"""Base class."""
import tempfile

import logging
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

from lc18report_dev.template import Template

logger = logging.getLogger(__name__)

class base:
    def __init__(self,base_info_file='',record_xlsx=''):
        self.base_number =[]
        self.sample_records =[]
        self.base_file = base_info_file
        self.record_xlsx=record_xlsx


    def _parse_base_file(self,avg_vaf,max_vaf,samples,yuedong_content):
        logger.info('Parsing base file.')
        UMIkinds_pd = pd.read_excel(self.base_file, sheet_name='UMIkinds')
        record_pd = pd.read_excel(self.record_xlsx,index_col="姓名")
        sample_record=record_pd.loc[samples[-1].name]
        df=pd.DataFrame(UMIkinds_pd)
        for i in range(len(sample_record.values)):
            col = sample_record.values[i]
            if str(col).startswith('Lib'):
                sum=df[df['Clinical Significance'].isin( ['可能致癌', '致癌'] )][col].sum()
                col=col.replace('Lib','A')
                self.sample_records.append({'id':col,'sum':sum,'time':str(sample_record.values[i+1])[0:10]})
        self.base_number.append(df.iloc[:,3:][df['Clinical Significance'].isin( ['可能致癌', '致癌'] )].sum())
        baseline=np.median(self.base_number)*3
        yuedong_content['img_4']=Template.IMG +str(self.tu_4(baseline))
        yuedong_content['img_1']=Template.IMG +str(self.tu_1(baseline))
        yuedong_content['img_2']=Template.IMG +str(self.tu_2())
        yuedong_content['img_3']=Template.IMG +str(self.tu_3())
        yuedong_content['img_5']=Template.IMG +str(self.tu_5(avg_vaf,samples))
        yuedong_content['hGe_graph']=Template.IMG +str(self.get_yuedong_content(max_vaf,samples))
        return yuedong_content
    #历次送检风险评估图
    def tu_1(self,baseline):
        img_file = tempfile.NamedTemporaryFile('wb', suffix='.png', delete=False)

        test_names =  [col['id'] for col in self.sample_records]
        test_values = [col['sum'] for col in self.sample_records]
        fig, ax = plt.subplots(figsize=(20, 16))
        ax.set_ylim(0, baseline*9+200)
        max_sum=baseline*9+200
        if int(max(test_values))>int(baseline)*9 :
            max_sum=max(test_values)+200
        ax.set_yticks([0,baseline,baseline*2,baseline*3,(baseline*9+baseline*3)/2,baseline*9,(max_sum+baseline*9)/2,max_sum],
        ["0",baseline,"低风险区  ",baseline*3,"中风险区   ",baseline*9,"高风险区   ","   "],
        fontproperties="SimHei")
        ax.plot(
            test_names, test_values,
            linewidth=1,
            color='royalblue',
            solid_capstyle='round',
            marker='o'
        )
        # for side in ['top', 'right', 'left']:
        #     ax.spines[side].set_visible(False)
        ax.grid(axis='y')
        zip_data = list(zip(test_names,test_values))
        for x,y in zip_data:
            for col in self.sample_records:
                if col['id']==x and col['sum']==y:
                    text = "time:"+col['time'] + "\n" + str(y)
                    if len(zip_data) > 4 and zip_data.index((x,y)) % 2 != 0:
                        text = "time:"+col['time'] + "\n\n\n" + str(y)
                    ax.text(x, y, text, fontsize=36, color = "r", style = "italic", weight = "light",
                            verticalalignment='bottom', horizontalalignment='left',rotation=0)
        ax.set_xlabel(self.sample_records[-1]['id'],fontsize=44)
        plt.tick_params(labelsize=40)
        plt.savefig(img_file, bbox_inches='tight')
        img_file.close()
        return img_file.name
    #相对初始ctDNA水平变化趋势图
    def tu_2(self):
        img_file = tempfile.NamedTemporaryFile('wb', suffix='.png', delete=False)

        test_names = np.linspace(1,len(self.sample_records),len(self.sample_records))
        test_values = []
        fig, ax = plt.subplots(figsize=(10, 6))
        t0=self.sample_records[0]['sum']
        if t0 == 0:
            t0 = 1
        x_name=1
        for col in self.sample_records:
            m=col['sum']/t0
            col['y']=m
            col['x']=x_name
            x_name=x_name+1
            test_values.append(m)
        ax.set_ylim(0, int(max(test_values))+2)
        ax.plot(
            test_names, test_values,
            linewidth=1,
            color='royalblue',
            solid_capstyle='round',
            marker='o',
        )
        for side in ['top', 'right', 'left']:
            ax.spines[side].set_visible(False)
        zip_data = list(zip(test_names,test_values))
        for x,y in zip_data:
            for col in self.sample_records:
                if col['x']==x and col['y']==y:
                    text = "time:"+col['time']+"\n"+"%.2f" % y
                    if len(zip_data) > 4 and zip_data.index((x,y)) % 2 != 0:
                        text = "time:"+col['time']+"\n\n\n"+"%.2f" % y
                    ax.text(x, y, text, fontsize=20, color = "r", style = "italic", weight = "light",
                            verticalalignment='bottom', horizontalalignment='left',rotation=0)
        ax.grid(axis='y')
        ax.set_xlabel(self.sample_records[-1]['id'],fontsize=20)
        #plt.ylabel("斜率",fontproperties="SimHei",fontsize=24)
        poly=np.polyfit(test_names,test_values,deg=1)
        z=np.polyval(poly,test_names)
        ax.plot(test_names,test_values,'o')
        ax.plot(test_names,z,label='y='+base.conversion_equation(str(np.poly1d(poly))),linewidth=3)
        ax.legend(loc='upper left', bbox_to_anchor=(0, 1.2),fontsize=20)
        plt.savefig(img_file, bbox_inches='tight')
        img_file.close()
        return img_file.name
    #全周期ctDNA水平变化趋势图
    def tu_3(self):
        img_file = tempfile.NamedTemporaryFile('wb', suffix='.png', delete=False)

        test_names = np.linspace(1,len(self.sample_records),len(self.sample_records))
        test_values = []
        fig, ax = plt.subplots(figsize=(10, 6))
        t0=self.sample_records[0]['sum']
        if t0 == 0:
            t0 = 1
        x_name=1
        for col in self.sample_records:
            m=col['sum']/t0
            t0 = 1 if col['sum'] == 0 else col['sum']
            col['y']=m
            col['x']=x_name
            x_name=x_name+1
            test_values.append(m)

        ax.set_ylim(0, int(max(test_values))+2)
        ax.plot(
            test_names, test_values,
            linewidth=1,
            color='royalblue',
            solid_capstyle='round',
            marker='o',
        )
        for side in ['top', 'right', 'left']:
            ax.spines[side].set_visible(False)
        zip_data = list(zip(test_names,test_values))
        for x,y in zip_data:
            for col in self.sample_records:
                if col['x']==x and col['y']==y:
                    text = "time:"+col['time']+"\n"+"%.2f" % y
                    if len(zip_data) > 4 and zip_data.index((x,y)) % 2 != 0:
                        text = "time:"+col['time']+"\n\n\n"+"%.2f" % y
                    ax.text(x, y, text, fontsize=20, color = "r", style = "italic", weight = "light",
                            verticalalignment='bottom', horizontalalignment='left',rotation=0)
        ax.grid(axis='y')
        ax.set_xlabel(self.sample_records[-1]['id'],fontsize=20)
        #plt.ylabel("斜率",fontproperties="SimHei",fontsize=24)
        poly=np.polyfit(test_names,test_values,deg=1)
        z=np.polyval(poly,test_names)
        ax.plot(test_names,test_values,'o')
        ax.plot(test_names,z,label='y='+base.conversion_equation(str(np.poly1d(poly))),linewidth=3)
        ax.legend(loc='upper left', bbox_to_anchor=(0, 1.2),fontsize=20)
        plt.savefig(img_file, bbox_inches='tight')
        img_file.close()
        return img_file.name
    #本次样本ctDNA绝对分子数图
    def tu_4(self,baseline):
        img_file = tempfile.NamedTemporaryFile('wb', suffix='.png', delete=False)

        test_names =  self.sample_records[-1]['id']
        test_values = self.sample_records[-1]['sum']
        fig, ax = plt.subplots(figsize=(10, 6))
        plt.rcParams['font.sans-serif']=['SimHei']
        if test_values<baseline:
            ax.set_ylim(0,baseline+200)
        else:
            ax.set_ylim(0,test_values+200)
        ax.plot(
            test_names, test_values,
            linewidth=4,
            color='royalblue',
            solid_capstyle='round',
            marker='o',
        )
        for side in ['top', 'right', 'left']:
            ax.spines[side].set_visible(False)
        ax.grid(axis='y')
        for col in self.sample_records:
            if col['id']==test_names and col['sum']==test_values:
                ax.text(test_names,test_values," "+str(test_values)+"  time:"+col['time'],
                fontsize=16, color = "r", style = "italic", weight = "light",
            verticalalignment='center', horizontalalignment='left',rotation=0)
        ax.set_xlabel(self.sample_records[-1]['id'],fontsize=16)
        plt.axhline(baseline,label='人群数据基线    '+'y='+str(baseline))
        ax.legend(loc='upper left', bbox_to_anchor=(0, 1.0))
        plt.savefig(img_file, bbox_inches='tight')
        img_file.close()
        return img_file.name
    #vm水平变化趋势图
    def tu_5(self,avg_vaf,samples):
        img_file = tempfile.NamedTemporaryFile('wb', suffix='.png', delete=False)

        test_names = np.linspace(1,len(self.sample_records),len(self.sample_records))
        test_values = []
        fig, ax = plt.subplots(figsize=(10, 6))
        vaf=[]
        for sample in samples :
            if sample!=samples[-1]:
                if sample.variants:
                    for var in sample.variants:
                        vaf.append(var['vaf'])
                if vaf and len(vaf):
                    avg_sum=sum(vaf)/len(vaf)
                else:
                    avg_sum=0
                if avg_sum>=80:
                    avg_sum=80
                test_values.append(eval(base.ctdna_ml(sample.hGe*avg_sum/100)))
                vaf.clear()
            else :
                if sample==samples[-1]:
                    test_values.append(eval(base.ctdna_ml(samples[-1].hGe*avg_vaf/100)))
                    continue
                test_values.append(0)
        if len(test_names) !=len(test_values):
            for i in range(len(test_names)-len(test_values)):
                test_values.insert(0,0)
        for i in range(len(self.sample_records)):
            self.sample_records[i]['x']=test_names[i]
            self.sample_records[i]['y']=test_values[i]
        ax.set_ylim(0, int(max(test_values))+200)
        ax.plot(
            test_names, test_values,
            linewidth=1,
            color='royalblue',
            solid_capstyle='round',
            marker='o',
        )
        for side in ['top', 'right', 'left']:
            ax.spines[side].set_visible(False)
        zip_data = list(zip(test_names,test_values))
        for x,y in zip_data:
            for col in self.sample_records:
                if col['x']==x and col['y']==y:
                    text = "time:"+col['time']+"\n"+str(y)
                    if len(zip_data) > 4 and zip_data.index((x,y)) % 2 != 0:
                        text = "time:"+col['time']+"\n\n\n"+str(y)
                    ax.text(x, y, text, fontsize=20, color = "r", style = "italic", weight = "light",
                            verticalalignment='bottom', horizontalalignment='left',rotation=0)
        ax.grid(axis='y')
        ax.set_xlabel(self.sample_records[-1]['id'],fontsize=20)
        poly=np.polyfit(test_names,test_values,deg=1)
        z=np.polyval(poly,test_names)
        ax.plot(test_names,test_values,'o')
        ax.plot(test_names,z,label='y='+base.conversion_equation(str(np.poly1d(poly))),linewidth=3)
        ax.legend(loc='upper left', bbox_to_anchor=(0, 1.2),fontsize=20)
        plt.savefig(img_file, bbox_inches='tight')
        img_file.close()
        return img_file.name
    #ctDNA当量水平变化趋势图
    def get_yuedong_content(self,max_vaf,samples):
        img_file = tempfile.NamedTemporaryFile('wb', suffix='.png', delete=False)

        test_names =np.linspace(1,len(self.sample_records),len(self.sample_records))
        test_values = []
        vaf=[]
        for sample in samples :
            if sample!=samples[-1]:
                if sample.variants:
                    for var in sample.variants:
                        vaf.append(var['vaf'])
                if vaf and len(vaf):
                    max_sum=max(vaf)
                else:
                    max_sum=0
                if max_sum >=80:
                    max_sum=80
                test_values.append(eval(base.ctdna_ml(sample.hGe*max_sum/100)))
                vaf.clear()
            else :
                if sample==samples[-1]:
                    test_values.append(eval(base.ctdna_ml(samples[-1].hGe*max_vaf/100)))
                    continue
                test_values.append(0)
        if len(test_names) !=len(test_values):
            for i in range(len(test_names)-len(test_values)):
                test_values.insert(0,0)
        for i in range(len(self.sample_records)):
            self.sample_records[i]['x']=test_names[i]
            self.sample_records[i]['y']=test_values[i]
        fig, ax = plt.subplots(figsize=(10, 6))
        ax.set_ylim(0, max(test_values) + 200)
        ax.plot(
            test_names, test_values,
            linewidth=1,
            color='royalblue',
            solid_capstyle='round',
            marker='o',
        )
        for side in ['top', 'right', 'left']:
            ax.spines[side].set_visible(False)
        zip_data = list(zip(test_names,test_values))
        for x,y in zip_data:
            for col in self.sample_records:
                if col['y']==y and col['x']==x:
                    text = "time:"+col['time']+"\n"+str(y)
                    if len(zip_data) > 4 and zip_data.index((x,y)) % 2 != 0:
                        text = "time:"+col['time']+"\n\n\n"+str(y)
                    ax.text(x, y, text, fontsize=20, color = "r", style = "italic", weight = "light",
                            verticalalignment='bottom', horizontalalignment='left',rotation=0)
        ax.grid(axis='y')
        ax.set_xlabel(samples[-1].id,fontsize=20)
        poly=np.polyfit(test_names,test_values,deg=1)
        z=np.polyval(poly,test_names)
        ax.plot(test_names,test_values,'o')
        ax.plot(test_names,z,label='y='+base.conversion_equation(str(np.poly1d(poly))),linewidth=3)
        ax.legend(loc='upper left', bbox_to_anchor=(0, 1.2),fontsize=20)
        plt.savefig(img_file, bbox_inches='tight')
        img_file.close()
        return img_file.name
#Convert into a formula 转换成公式
    def conversion_equation(equation):
        if ('e' or 'E') in equation:
            eqlist=equation.split('x')
            x='x+'
            if '-' in str(base.ctdna_ml(eval(eqlist[1]))):
                x='x'
            equation=str(base.ctdna_ml(eval(eqlist[0])))+x+str(base.ctdna_ml(eval(eqlist[1])))
        return equation
    def ctdna_ml(ml):
        if '.' not in str(ml) or ml==0 or ml==0.0:
            return str(int(ml))
        sum_right=len(str(ml).split(".")[1])
        sum_left=len(str(ml).split(".")[0])
        SIGN=0
        if '-' in str(ml):
            SIGN=1
        if sum_left>=4+SIGN :
            ml='%.0f' % float(ml)
        if sum_left==3+SIGN or (sum_left==1+SIGN and sum_right<2):
            ml='%.1f' % float(ml)
        if sum_left<=2+SIGN and sum_right>=2:
            ml='%.2f' % float(ml)
        return ml