import os
from flask import Flask, flash, request, redirect, url_for, render_template, send_from_directory

from werkzeug.utils import secure_filename

from PIL import Image, ImageOps
import pytesseract
import cv2
import numpy as np
from pytesseract import Output

import io
import base64

import numpy as np

from pathlib import Path

from pdf2image import convert_from_path

from scipy.ndimage import interpolation as inter


#import phunspell

def correct_skew(image, delta=1, limit=5):
    def determine_score(arr, angle):
        data = inter.rotate(arr, angle, reshape=False, order=0)
        histogram = np.sum(data, axis=1, dtype=float)
        score = np.sum((histogram[1:] - histogram[:-1]) ** 2, dtype=float)
        return histogram, score

    if len(image.shape)==3:
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    else:
        gray = image
    thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1] 

    scores = []
    angles = np.arange(-limit, limit + delta, delta)
    for angle in angles:
        histogram, score = determine_score(thresh, angle)
        scores.append(score)

    best_angle = angles[scores.index(max(scores))]

    (h, w) = image.shape[:2]
    center = (w // 2, h // 2)
    M = cv2.getRotationMatrix2D(center, best_angle, 1.0)
    corrected = cv2.warpAffine(image, M, (w, h), flags=cv2.INTER_CUBIC, \
            borderMode=cv2.BORDER_REPLICATE)

    return best_angle, corrected

app = Flask(__name__)

UPLOAD_FOLDER = 'files/upload/'
OUTPUT_FOLDER = 'files/download/'
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'bmp', 'webp', 'pdf'}

app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER

def allowed_file(filename):
    return '.' in filename and \
           filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

def isPDF(filename):
    return '.' in filename and \
           filename.rsplit('.', 1)[1].lower() in {'pdf'}

@app.route('/', methods=['GET', 'POST'])
def index():
    cwd = os.getcwd()
    fd = os.path.join(cwd , 'files/download')
    print(fd)
    if(os.path.isdir(fd)==False):
        os.mkdir(fd)

    fu = os.path.join(cwd , 'files/upload')
    if(os.path.isdir(fu)==False):
        os.mkdir(fu)  

    if request.method == 'GET':
            return render_template('index.html', files=os.listdir(fd))
    else:
        return render_template('index.html', files=os.listdir(fu))



@app.route('/download/<filename>')
def download_file(filename):
    return send_from_directory(OUTPUT_FOLDER, filename, as_attachment=True)

@app.route('/delete/<filename>')
def delete_file(filename):
    try:
        os.remove(OUTPUT_FOLDER + filename)
        return render_template('index.html', files=os.listdir(OUTPUT_FOLDER))
    except:
        flash('There was a problem deleting that file')
        return redirect(request.url)

@app.route('/makeCut', methods=['POST'])
def makeCut():
    if 'file' not in request.files:
        flash('No file part', 'error')
        return redirect(request.url)

    file = request.files['file']

    if allowed_file(file.filename):
        filename = secure_filename(file.filename)
        file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
        #file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
        f = os.path.join(UPLOAD_FOLDER , filename)


        pdfFile = False


        if isPDF(filename):
            pdfFile = True
            image = convert_from_path(f)[0]
        else:
            image = Image.open(f)

        new_width = 400
        aspect_ratio = image.width / image.height
        new_height = int(new_width / aspect_ratio)

        image = image.resize((new_width, new_height))
        
        img_byte_array = io.BytesIO()
        image.save(img_byte_array, format='JPEG')
        img_base64 = base64.b64encode(img_byte_array.getvalue()).decode('utf-8')

        return render_template('selectRegion.html', image_data=img_base64)

def makeTransform(pdfFile, image, filename):
    #preprocess to improve quality of results
    #Add border
    img_with_border = ImageOps.expand(image, border=50, fill='red')
    image_np = np.array(img_with_border)
    clahe = cv2.createCLAHE(clipLimit=1)

    angle, rot_img = correct_skew(image_np)

    cv2.imwrite("files/download/correct_skew.jpg", image_np) 

    #Scanned documents are ok, CLAHE is not needed
    if(pdfFile==False):
        if len(rot_img.shape)==3:
            image_bw_rot = cv2.cvtColor(rot_img, cv2.COLOR_BGR2GRAY)
            final_img_rot = clahe.apply(image_bw_rot) + 1
        else:
            final_img_rot = clahe.apply(rot_img) + 1
    else:
        final_img_rot = cv2.cvtColor(rot_img, cv2.COLOR_BGR2GRAY)
        
    #  final_img_rot_1 = clahe.apply(image_bw_rot) + 0.5
    #final_img_rot_0 = clahe.apply(image_bw_rot)
    #cv2.imwrite("files/download/final_img_rot_1.jpg", final_img_rot_1) 
    #cv2.imwrite("files/download/final_img_rot_0.jpg", final_img_rot_0) 


    custom_config = r'-l ces --oem 1 --psm 6' 
    text = pytesseract.image_to_string(image,config=custom_config)

    text_opraveno = pytesseract.image_to_string(final_img_rot,config=custom_config)

    cv2.imwrite("files/download/upraveno.jpg", final_img_rot) 

   # text2 = text.encode(encoding = 'UTF-8', errors = 'strict')
    fout = os.path.join(OUTPUT_FOLDER , Path(filename).stem) + ".txt"
    os.remove(os.path.join(UPLOAD_FOLDER , filename))

    return text, text_opraveno

@app.route('/transformWC', methods=['POST'])
def transformFileWC():
    documentType = request.form["docType"]
    f = request.form["img"]
    pdfFile = request.form["pdfFile"]
    filename = request.form["filename"]

    if isPDF(filename):
        pdfFile = True
        image = convert_from_path(f)[0]
    else:
        image = Image.open(f)

    text, text_opraveno = makeTransform(pdfFile, image, filename)



    return render_template('output.html', text=text, text_opraveno=text_opraveno)

@app.route('/transform', methods=['POST'])
def transformFile():
    print(request.files)
    if 'file' not in request.files:
        flash('No file part', 'error')
        return redirect(request.url)

    file = request.files['file']

    documentType = request.form["docType"]

    selectPart = request.form["selPart"]
    


    if file.filename == '':
        flash('No selected file')
        return redirect(request.url)

    if allowed_file(file.filename):
        filename = secure_filename(file.filename)
        file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
        #file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
        f = os.path.join(UPLOAD_FOLDER , filename)
        # checking if it is a file
        pdfFile = False
        if isPDF(filename):
            pdfFile = True
            image = convert_from_path(f)[0]
        else:
            image = Image.open(f)
        if(selectPart=="True"):
            print("Udelat vyrez")
            new_width = 500
            aspect_ratio = image.width / image.height
            new_height = int(new_width / aspect_ratio)

            image = image.resize((new_width, new_height))
        
            img_byte_array = io.BytesIO()
            image.save(img_byte_array, format='JPEG')
            img_base64 = base64.b64encode(img_byte_array.getvalue()).decode('utf-8')
            return render_template('selectRegion.html', image_data=img_base64, images=f, pdfFile=pdfFile, filename=filename, documentType=documentType)
        else:

            text, text_opraveno = makeTransform(pdfFile, image, filename)

            return render_template('output.html', text=text, text_opraveno=text_opraveno)
    else:
        flash('Not suported file format')
        return redirect(request.url)
    

if __name__=="__main__":
    app.run(debug=True)