import openshot
import re
from PIL import Image,ImageDraw,ImageFont
import pandas as pd
import os
import cv2
import numpy as np
# import moviepy.editor as mp
import time
import pysrt
import shutil
import rpyc
import random
import string
import requests
from bs4 import BeautifulSoup
import zipfile
import csv
from datetime import datetime
def cKey(r,g,b,fuzz):
    col=openshot.Color()
    col.red=openshot.Keyframe(r)
    col.green=openshot.Keyframe(g)
    col.blue=openshot.Keyframe(b)
    return openshot.ChromaKey(col, openshot.Keyframe(fuzz))

def video_writer_init(path):
    w = openshot.FFmpegWriter(path)
    w.SetAudioOptions(True, "aac", 44100, 2, openshot.LAYOUT_STEREO, 3000000)
    w.SetVideoOptions(True, "libx264", openshot.Fraction(30000, 1000), 1280, 720,
        openshot.Fraction(1, 1), False, False, 3000000)
    return w

def video_photo_clip(video=None,layer=None, position=None, end=None
    ,scale_x=1,scale_y=1,location_x=0,location_y=0,ck=None,audio=True):
    clip = openshot.Clip(video)
    clip.Layer(layer)
    clip.Position(position)
    clip.End(end)
    clip.scale_x=openshot.Keyframe(scale_x)
    clip.scale_y=openshot.Keyframe(scale_y)
    clip.location_x=openshot.Keyframe(location_x)
    clip.location_y=openshot.Keyframe(location_y)
    
    if ck!=None:
        clip.AddEffect(ck)
    if audio==True:
        clip.has_audio=openshot.Keyframe(1)
    else:
        clip.has_audio=openshot.Keyframe(0)
    return clip

def trim_punctuation(s):
    pat_block = u'[^\u4e00-\u9fff0-9a-zA-Z]+'
    pattern = u'([0-9]+{0}[0-9]+)|{0}'.format(pat_block)
    res = re.sub(pattern, lambda x: x.group(1) if x.group(1) else u" " ,s)
    return res


def randomString(stringLength=10):
    letters = string.ascii_lowercase
    return ''.join(random.choice(letters) for i in range(stringLength))



#文字轉圖片
def txt2image(content, save_target,lang='zh',size=26,fon="input_self/font/DFT_B7.ttc"):
    unicode_text = trim_punctuation(content)
    font = ''
    if lang=='zh':
        font = ImageFont.truetype(font=fon, size=size)
    else :
        font = ImageFont.truetype(font="input_self/font/arial.ttf", size=size)
    
    W, H = (1280,500)
    canvas = Image.new('RGB', (W, H), "#00FF00")
    draw = ImageDraw.Draw(canvas)
    
    text= content
    if "\n" in text:
        w, h = draw.textsize(text.split("\n")[0],font = font)
        #draw.text(((W-w)/2,0), text[0:18],'black', font)
        text_border(draw,(W-w)/2,0,text.split("\n")[0],font,'black','white')
        w, h = draw.textsize(text.split("\n")[1],font = font)
        #draw.text(((W-w)/2,h+2), text[18:],'black', font)
        text_border(draw,(W-w)/2,h+2,text.split("\n")[1],font,'black','white')
    else:
        w, h = draw.textsize(content,font = font)
        #draw.text(((W-w)/2,0), text,'black', font)
        text_border(draw,(W-w)/2,0,text,font,'black','white')
    canvas.save(save_target, "PNG")

def text_border(draw,x,y,text,font,shadowcolor,fillcolor):
    draw.text((x-1, y), text, font=font, fill=shadowcolor)
    draw.text((x+1, y), text, font=font, fill=shadowcolor)
    draw.text((x, y-1), text, font=font, fill=shadowcolor)
    draw.text((x, y+1), text, font=font, fill=shadowcolor)

    draw.text((x-1, y+1), text, font=font, fill=shadowcolor)
    draw.text((x+1, y-1), text, font=font, fill=shadowcolor)
    draw.text((x-1, y-1), text, font=font, fill=shadowcolor)
    draw.text((x+1, y+1), text, font=font, fill=shadowcolor)
    # thicker border
    draw.text((x-2, y-2), text, font=font, fill=shadowcolor)
    draw.text((x+2, y-2), text, font=font, fill=shadowcolor)
    draw.text((x-2, y+2), text, font=font, fill=shadowcolor)
    draw.text((x+2, y+2), text, font=font, fill=shadowcolor)

    # now draw the text over it
    draw.text((x, y), text, font=font, fill=fillcolor)

def srt_to_csv(srt_file):
    subs = pysrt.open(srt_file)

    
    csv_file = srt_file.split('.')[0] + ".csv"
    with open(csv_file, 'w', newline='',encoding="big5") as csvfile:
        # 建立 CSV 檔寫入器
        writer = csv.writer(csvfile)
        j=0
        for context in subs:
            writer.writerow([context.index, context.start,context.end, context.text])
            j+=1
    return csv_file

def csv_to_text(csv_file,text_font):
    text_form = []
    with open(csv_file, newline='',encoding="big5") as csvfile:

        # 讀取 CSV 檔案內容
        rows = csv.reader(csvfile)

        j=0
        # 以迴圈輸出每一列
        for row in rows:

            if j==0:
                j = 1
                continue
            
            start = datetime.strptime(row[1], "%H:%M:%S,%f")
            end = datetime.strptime(row[2], "%H:%M:%S,%f") - datetime.strptime(row[1], "%H:%M:%S,%f")
            end_timeStamp=end.seconds+0.000001*end.microseconds
            start_timeStamp=start.minute*60+start.second+ 0.000001*start.microsecond
            text_form.append({'text':row[3],'start':start_timeStamp,'end':end_timeStamp,'size':36,'font':text_font})
            
    return text_form
def text_to_short_vedio(mp4_file ,sound_file,output_filename,text_font):
    t = openshot.Timeline(1280, 720, openshot.Fraction(30000, 1000), 44100, 2, openshot.LAYOUT_STEREO)
    t.Open()
    
    # 去背參數
    ck = cKey(0, 254, 0, 270)
    ck_anchor = cKey(0, 255, 0, 320)

    anchor = openshot.FFmpegReader(mp4_file)
    anchor.Open()
    anchor_clip = video_photo_clip(video=anchor,layer=2,scale_x=1,scale_y=1,
            location_x=0,location_y=0,position=0, end=anchor.info.duration,audio=True)
    t.AddClip(anchor_clip)
    anchor.Close()
    number = 0

    # sound_srt_file = ""
    # #音檔自動產生srt(逐字稿)
    # if ".srt" in sound_file:
    #     sound_srt_file = sound_file
    # elif not sound_file is None:
    #     cmd = "autosub -S zh-TW -D zh-TW " + sound_file
    #     os.system(cmd)
    #     sound_srt_file = sound_file.split('.')[0] + ".srt"
    # csv_file = srt_to_csv(sound_srt_file)
    csv_file = "output/csv_produce/test.csv"

    text_form = csv_to_text(csv_file,text_font)
 

    # print(sound_srt_file)
    #開啟srt檔
    try:
        number = 0
        for text_tmp in text_form:
            file_name = "input_self/tmp/save_target_" + str(number) + ".png"
            txt2image(text_tmp['text'], file_name,lang='zh',size = text_tmp['size'],fon = text_tmp['font'])
            exec('text_anchor_{} = openshot.QtImageReader("input_self/tmp/save_target_{}.png")'.format(number,number))
            exec('text_anchor_{}.Open()'.format(number))
            exec('text_anchor_{}.Open()'.format(number))
            exec('text_anchor_clip_{} = video_photo_clip(video=text_anchor_{},layer=4,scale_x=1,scale_y=1,\
                    location_x=0,location_y=0.78,position=text_tmp["start"], end=text_tmp["end"],ck=ck_anchor,audio=True)'.format(number,number))
            exec('t.AddClip(text_anchor_clip_{})'.format(number))
            exec('text_anchor_{}.Close()'.format(number))
            number = number+1
    except:
        print("無法開啟srt檔案(字幕產生失敗)")

    w = video_writer_init(output_filename)
    w.Open()

    frames = int(t.info.fps)*int(anchor.info.duration)
    for n in range(frames):
        f=t.GetFrame(n)
        w.WriteFrame(f)

    t.Close()
    w.Close()

    # 刪除暫存檔案
    shutil.rmtree('input_self/tmp')
    os.mkdir('input_self/tmp')
    # shutil.rmtree('input_self/tmp1')
    # os.mkdir('input_self/tmp1')


if __name__ == '__main__':
	# text_to_short_vedio_create()
	text_to_short_vedio(mp4_file = "output/no_captions/test.mp4",sound_file ='output/no_captions/test.mp4',
        output_filename="output/finally_output/demo.mp4",text_font ="input_self/font/DFT_R7.ttc")