#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, "基本信息,北京九零科技有限公司,成立于2015年,位于北京市,是一家以从事科技推广和应用服务业为主的企业。企业注册资本500万人民币。")
        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 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.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------------')