#encoding = utf8
import json
import logging
from logging import handlers
import tkinter
import tkinter.messagebox
import customtkinter
import requests
from PIL import Image, ImageTk

from Human import Human
from tts.EdgeTTS import EdgeTTS

logger = logging.getLogger(__name__)

customtkinter.set_appearance_mode("System")  # Modes: "System" (standard), "Dark", "Light"
customtkinter.set_default_color_theme("green")  # Themes: "blue" (standard), "green", "dark-blue"


class App(customtkinter.CTk):
    def __init__(self):
        super().__init__()

        self._tts_url = 'http://localhost:8080'

        # configure window
        self.title("数字人测试demo")
        self.geometry(f"{1100}x{580}")

        self.grid_columnconfigure(1, weight=1)
        self.grid_rowconfigure((0, 1), weight=1)

        self.image_frame = customtkinter.CTkFrame(self, corner_radius=10)
        self.image_frame.grid(row=0, column=0, rowspan=2, columnspan=3,
                                padx=(20, 20), pady=(20, 0), sticky="nsew")
        self.image_frame.grid_rowconfigure(0, weight=1)
        self.logo_label = customtkinter.CTkLabel(self.image_frame, text="CustomTkinter",
                                                 font=customtkinter.CTkFont(size=20, weight="bold"))
        # self.logo_label.grid(row=0, column=0, padx=20, pady=(20, 10))

        self.entry = customtkinter.CTkEntry(self, placeholder_text="输入内容")
        self.entry.grid(row=2, column=0, columnspan=2, padx=(20, 0), pady=(20, 20), sticky="nsew")

        self.main_button_1 = customtkinter.CTkButton(master=self, fg_color="transparent", border_width=2,
                                                     text_color=("gray10", "#DCE4EE"), text='发送',
                                                     command=self.request_tts)
        self.main_button_1.grid(row=2, column=2, padx=(20, 20), pady=(20, 20), sticky="nsew")

        self._init_image_canvas()

        self._human = Human()
        tts = EdgeTTS(self._human)
        self._human.set_tts(tts)
        self._render()

    def on_destroy(self):
        logger.info('------------App destroy------------')
        self._human.on_destroy()

    def _init_image_canvas(self):
        self._canvas = customtkinter.CTkCanvas(self.image_frame)
        self._canvas.pack(fill=customtkinter.BOTH, expand=customtkinter.YES)

    def _render(self):
        image = self._human.render()
        if image is None:
            self.after(100, self._render)
            return

        img = Image.fromarray(image)
        imgtk = ImageTk.PhotoImage(image=img)

        self._canvas.delete("all")

        self._canvas.imgtk = imgtk

        width = self.winfo_width() * 0.5
        height = self.winfo_height() * 0.5

        self._canvas.create_image(width, height, anchor=customtkinter.CENTER, image=imgtk)
        self._canvas.update()
        self.after(30, self._render)

    def request_tts(self):
        content = self.entry.get()
        print('content:', content)
        self.entry.delete(0, customtkinter.END)
        self._human.read(content)
        # payload = {
        #   'text': content,
        #   'voice': 'zh-CN-XiaoyiNeural'
        # }
        # resp = requests.get(self._tts_url + '/tts', params=urlencode(payload))
        # if resp.status_code != 200:
        #     print('tts error', resp.status_code)
        #     return
        #
        # print(resp.content)
        #
        # resJson = json.loads(resp.text)
        # url = resJson.get('url')
        # self.download_tts(url)

    def download_tts(self, url):
        file_name = url[3:]
        print(file_name)
        download_url = self._tts_url + url
        print('download tts', download_url)
        resp = requests.get(download_url)
        with open('./audio/mp3/' + file_name, 'wb') as mp3:
            mp3.write(resp.content)

        from pydub import AudioSegment
        sound = AudioSegment.from_mp3('./audio/mp3/' + file_name)
        sound.export('./audio/wav/' + file_name + '.wav', format="wav")

        # open('./audio/', 'wb') with


def config_logging(file_name: str, console_level: int=logging.INFO, file_level: int=logging.DEBUG):
    file_handler = logging.FileHandler(file_name, mode='a', encoding="utf8")
    file_handler.setFormatter(logging.Formatter(
        '%(asctime)s [%(levelname)s] %(module)s.%(lineno)d %(name)s:\t%(message)s'
        ))
    file_handler.setLevel(file_level)

    console_handler = logging.StreamHandler()
    console_handler.setFormatter(logging.Formatter(
        '[%(asctime)s %(levelname)s] %(message)s',
        datefmt="%Y/%m/%d %H:%M:%S"
        ))
    console_handler.setLevel(console_level)

    logging.basicConfig(
        level=min(console_level, file_level),
        handlers=[file_handler, console_handler],
        )


if __name__ == "__main__":
    # logging.basicConfig(filename='./logs/info.log', level=logging.INFO)
    config_logging('./logs/info.log', logging.INFO, logging.INFO)

    logger.info('------------start------------')
    app = App()
    app.mainloop()
    app.on_destroy()
    # logger.info('------------exit------------')