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

from playsound import playsound

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("TTS 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.insert(0, "大家好,我是九零科技有限公司,虚拟数字人。")
        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._is_play_audio = False
        self._human = Human()
        self._render()
        # self.play_audio()

    def destroy(self):
        self.on_destroy()
        super().destroy()

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

    def play_audio(self):
        return
        # if self._is_play_audio:
        #     return
        # self._is_play_audio = True
        # file = os.path.curdir + '/audio/test1.wav'
        # print(file)
        # winsound.PlaySound(file, winsound.SND_ASYNC or winsound.SND_FILENAME)
        # playsound(file)

    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

        # self.play_audio()
        iheight, iwidth = image.shape[0], image.shape[1]
        width = self.winfo_width()
        height = self.winfo_height()
        if iheight / iwidth >= width / height:
            image = cv2.resize(image, (int(width), int(iheight * width / iwidth)))
        else:
            image = cv2.resize(image, (int(iwidth * height / iheight), int(height)), interpolation=cv2.INTER_AREA)
            # image = cv2.resize(image, (int(width), int(height)), interpolation=cv2.INTER_AREA)

        # image = cv2.resize(image, (int(width), int(height)), interpolation=cv2.INTER_AREA)

        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(40, self._render)

    def request_tts(self):
        content = self.entry.get()
        # content = ''
        print('content:', content)
        self.entry.delete(0, customtkinter.END)
        self._human.pause_talk()
        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------------')