import os
import zipfile
import threading
import time
import models as db
import subprocess
import psutil
import re
from datetime import date
import models
import time

UPLOAD_FOLDER=os.path.join(os.path.expanduser('~'), '.arquivos_api')
PASTA_SRC=os.path.join(os.path.expanduser('~'), 'api/estrutura_api/api/utils')


def excluir_arquivo(path_file):
    """Efetua a exclusão do arquivo selecionado em -> 'path_file' """
    time.sleep(10)
    file_name=str(path_file)
    os.remove(path_file)
    print(f'Arquivo removido: {file_name}')
    return

class FormatarData:
    def formatar_data(data=int(date.today().month)-1,mode='str_format'):
        if mode=='str_format':
            mes_formatado=None
            match data:
                case '01'| 1:
                    mes_formatado=f'{data}-jan'
                case '02'|2:
                    mes_formatado=f'{data}-fev'
                case '03'|3:
                    mes_formatado=f'{data}-mar'
                case '04'|4:
                    mes_formatado=f'{data}-abr'
                case '05'|5:
                    mes_formatado=f'{data}-mai'
                case '06'|6:
                    mes_formatado=f'{data}-jun'
                case '07'|7:
                    mes_formatado=f'{data}-jul'
                case '08'|8:
                    mes_formatado=f'{data}-ago'
                case '09'|9:
                    mes_formatado=f'{data}-set'
                case '10'|10:
                    mes_formatado=f'{data}-out'
                case '11'|11:
                    mes_formatado=f'{data}-nov'
                case '12'|12:
                    mes_formatado=f'-{data}-dez'
        if mode=='int':
            mes_formatado=int(re.sub(r'\D','',str(data)))
        
        return mes_formatado

class ZiparArquivos:
    def zipar(mes, modelos:list, mode='global',cnpj=None, ano=date.today().year):
        pasta_zipada=f"arquivos_{mes}.zip"
        try:
            match mode:
                case "global":
                    empresas=[i for i in db.SQLConn().parametro_read()]
                    for emp in empresas:
                        try:
                            with zipfile.ZipFile(f"{PASTA_SRC}/temp/arquivos_zipado/{pasta_zipada}","a", zipfile.ZIP_DEFLATED) as zip:
                                for p in modelos:
                                    if p=="nfe" or p=="nfse":
                                        subpasta=f"{UPLOAD_FOLDER}/{emp["cnpj"]}/{mes}/{ano}/{p}/xml"
                                    else:
                                        subpasta=f"{UPLOAD_FOLDER}/{emp["cnpj"]}/{mes}/{ano}/{p}"
                            
                                    for raiz, _, arquivos in os.walk(subpasta):
                                        for arquivo in arquivos:
                                            print(arquivo)
                                            caminho_completo=os.path.join(raiz, arquivo)
                                            nome_relativo=os.path.relpath(caminho_completo, emp["razao"])
                                            if emp["razao"]:
                                                pasta_acoplada=os.path.join(f"{emp["razao"]}/{p}", os.path.basename(nome_relativo))
                                            else:
                                                pasta_acoplada=os.path.basename(nome_relativo)
                                            zip.write(caminho_completo, pasta_acoplada)
                        except Exception as e:
                            print(f"Error -> {e}")
                            continue

                case "local":
                    try:
                        nome_emp=db.SQLConn().parametro_readline(param=['cnpj',f"{cnpj}"])["razao"]
                        with zipfile.ZipFile(f"{PASTA_SRC}/temp/arquivos_zipado/{pasta_zipada}","a", zipfile.ZIP_DEFLATED) as zip:
                            for p in modelos:
                                try:
                                    if p=="nfe" or p=="nfse":
                                        subpasta=f"{UPLOAD_FOLDER}/{cnpj}/{mes}/{ano}/{p}/xml"
                                    else:
                                        subpasta=f"{UPLOAD_FOLDER}/{cnpj}/{mes}/{ano}/{p}"
                            
                                    for raiz, _, arquivos in os.walk(subpasta):
                                        for arquivo in arquivos:
                                            print(arquivo)
                                            caminho_completo=os.path.join(raiz, arquivo)
                                            nome_relativo=os.path.relpath(caminho_completo, nome_emp)
                                            if nome_emp:
                                                pasta_acoplada=os.path.join(f"{nome_emp}/{p}", os.path.basename(nome_relativo))
                                            else:
                                                pasta_acoplada=os.path.basename(nome_relativo)
                                            zip.write(caminho_completo, pasta_acoplada)
                                except:
                                    continue
                    except Exception as e:
                        print(f"Error -> {e}")
                        
                case "singular":
                    pass

            time.sleep(5)
        except Exception as e:
            return f'Erro -> {e}'

        finally:
            if pasta_zipada:
                threading.Thread(target=excluir_arquivo, args=(os.path.join(PASTA_SRC, f"temp/arquivos_zipado/{pasta_zipada}"),)).start()
                return [os.path.join(PASTA_SRC, f"temp/arquivos_zipado"), pasta_zipada]

from api.utils.bots import sefaz_arquivos as sf

def worker_():
    try:
        sf.RequesteInit.iniciar()
    except Exception as e:
        print(f"Erro ao iniciar bots -> {e}")

    print(f'EXTRAÇÃO FINALIZADA...efetuando desligamento')
    # try:
    #     subprocess.run(["shutdown","/s","/t","0"], check=True)
    # except subprocess.CalledProcessError as e:
    #     print(f"Erro ao desligar maquina {e}")
    
    return

# def worker_0():
#     emp=[i['cnpj'] for i in models.SQLConn().parametro_read()]
#     sefaz_arquivos.RequestGuias(empresa=emp, cliente='192.168.1.186')
#     return

class ApiExec:
    def __init__(self):
        self.pasta=os.path.join(os.path.expanduser("~"),"api")
    def finalizar(self):
        time.sleep(5)
        subprocess.run([f"{self.pasta}/finalizar_api.bat"])  
    def iniciar(self):
        time.sleep(5)
        subprocess.run([f"{self.pasta}/iniciar_api.bat"])
    def resetar(self):
        time.sleep(5)
        subprocess.run([f"{self.pasta}/resetar_api.bat"])

def parar_processo(nome_processo, reset=False):
    time.sleep(5)
    processos=[]
    nome_processo=nome_processo
    
    for proc in psutil.process_iter(['pid','name','username','memory_info']):
        try:
            info={
                'pid':proc.info['pid'],
                'nome':proc.info['name'],
                'usuario':proc.info['username'],
                'memoria_MB':round(proc.info['memory_info'].rss /1024/1024, 2)
            }
            processos.append(info)
        except:
            continue
    for i in processos:
       
        try:
            if i['nome']==nome_processo or i['nome']=='chrome.exe' or i['nome']=='cmd.exe' or i['nome']=='WindowsTerminal.exe' or i['nome']=='OpenConsole.exe':
                print(f"{i['nome'] - {i['pid']}}")
                processo=psutil.Process(i['pid'])
                processo.terminate()
                processo.wait(timeout=5)
            time.sleep(0.5)
        except:
            continue

    return 

