import dash
from dash.dependencies import Input, Output, State
import dash_core_components as dcc
import dash_html_components as html
import dash_table

import plotly.express as px
import pandas as pd

import requests
from bs4 import BeautifulSoup
import re
from newspaper import Article

import sys
module_path = './question_answering'
if module_path not in sys.path:
    sys.path.append(module_path)
from question_answering_inference_utility import question_answering




# ------------------------------ LAYOUT CONTAINERS ------------------------------
# The main page will be divided in two columns.
# We'll define them right away.


# 1st column:
col_1 = html.Div(
    className='column-left',
    children=[
        html.Div([
            # Where the content of the tabs will be showed:
            html.B(
                children='The article must be in English.'
            ),

            dcc.Input(
                id="input_url",
                type="url",
                placeholder="Source URL",
                required=True,
                style=dict(
                    width='100%'
                )
            )
        ]),

        # Radiobuttons for choosing parser:
        html.Div([
            html.Div('Parser:'),

            dcc.RadioItems(
                id='radiobuttons-parser',
                options=[
                    {'label': "lxml: newspaper3k's default parser", 'value': 'lxml'},
                    {'label': "html.parser: Python's default parser",
                    'value': 'html.parser'},
                    {'label': 'html5lib: Extremely lenient but quite slow',
                    'value': 'html5lib'},
                ],
                value='lxml'
            )
        ]),

        # Button to extract text from the give url:
        html.Button(
            id='extract-button-state',
            n_clicks=0,
            children='Extract',
            style=dict(
                width='100%'
            )
        ),

        # Div to debug:
        html.Div(id='output-state-extract')
    ]
)



# 2nd column:
col_2 = html.Div(
    className='column-right',
    children=[
        # Text area for the extracted text from the URL:
        html.Div('Extracted text:'),

        dcc.Textarea(
            id='textarea-processed-url',
            className='extracted-text',
            value='Textarea content initialized\nwith multiple lines of text',
            persistence=True,
            readOnly=True,
        )]
)



# Input question container:
input_question_container = html.Div(
    children=[
        html.Div(
            style={'margin-bottom': '10px'},
            children=[
                html.Div('Question:'),

                dcc.Input(
                    id="input-question",
                    type='text',
                    placeholder="Please enter your question.",
                    style=dict(
                        width='100%',
                    )
                )
            ]
        ),

        # Checkbutton for filtering numbers:
        dcc.Checklist(
            id='checkbutton',
            options=[
                {'label': 'Filter numbers', 'value': '1'},
            ],
            value=['1']
        ),
    ]
)
    


# Submit button container:
submit_button_container = html.Div(
    children=[
        html.Div(
            className='center',
            children=[
                html.Button(
                    id='submit-button-state',
                    className='submit-button',
                    n_clicks=0,
                    children='Submit')
            ],
            style=dict(
                margin='20px'
            )
        ),

        # Div to debug:
        html.Div(id='output-state-submit')
    ]
)




# ------------------------------ FINAL LAYOUT ------------------------------
layout = html.Div(
    className='main',
    children=[
        html.H1(
            children='T5 Text Extraction Demo',
            style={'textAlign': 'center'}
        ),

        html.Div(
            className="row",
            children=[
                col_1,
                col_2
            ]
        ),

        # Horizontal separator:
        html.Hr(),

        input_question_container,

        submit_button_container
    ]
)






# ------------------------------ CALLBACKS ------------------------------

# Callback for when the Extract button has been pressed:
@app.callback(
    [
        Output('output-state-extract', 'children'),
        Output('textarea-processed-url', 'value')
    ],
    [
        Input('extract-button-state', 'n_clicks')
    ],
    [
        State('input_url', 'value'),
        State('radiobuttons-parser', 'value')
    ]
)
def update_output_extract_button(n_clicks, url, parser):
    children = ''

    # Web scrapping
    if url is None:
        return children, ''

    else:
        regex_url = r"https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)"
        if re.match(regex_url, url) is None:
            children += '\nIncorrect url!'
            return children, ''

        else:
            article = Article(url=url, language='en')

            article.download()

            article.parse()
            title = article.title
            


            article.nlp()
            keywords = article.keywords

            if parser=='lxml':
                extracted_txt = article.text
            
            else:
                resp = requests.get(url)
                html_doc = resp.text
                soup = BeautifulSoup(html_doc, 'html.parser')
                extracted_txt = re.sub(r'(\n| )+', ' ', soup.text)
            
            children += f'Title: {title}, keywords: {keywords}, parser: {parser}'

            return children, extracted_txt



# Callback for when the Submit button has been pressed:
@app.callback(
    Output('output-state-submit', 'children'),
    [
        Input('submit-button-state', 'n_clicks')
    ],
    [
        State('textarea-processed-url', 'value'),
        State('input-question', 'value'),
        State('checkbutton', 'value')
    ]
)
def update_output_extract_button(n_clicks, processed_txt, question, checkbutton_value):
    # Question answering:
    if n_clicks >= 1:
        if len(processed_txt) == 0:
            return 'Please enter a proper URL.'
        
        elif question is None:
            return 'Please enter a question.'
        
        else:
            answer, paragraph, prob = question_answering(
                query=question, text=processed_txt, filter_numbers=checkbutton_value)

            children = [
                html.P(f'Asked question: "{question}"'),
                html.P(f'Answer: {answer}'),
                html.P(f'Paragraph: {paragraph}'),
                html.P(f'Probability: {prob}')
            ]
            return children

    else:
        return ''



import dash
from dash.dependencies import Input, Output, State
import dash_core_components as dcc
import dash_html_components as html
import dash_table

import plotly.express as px
import pandas as pd

import requests
from bs4 import BeautifulSoup
import re
from newspaper import Article

import sys
module_path = './question_answering'
if module_path not in sys.path:
    sys.path.append(module_path)
from question_answering_inference_utility import question_answering




# ------------------------------ LAYOUT CONTAINERS ------------------------------
# The main page will be divided in two columns.
# We'll define them right away.


# 1st column:
col_1 = html.Div(
    className='column-left',
    children=[
        html.Div([
            # Where the content of the tabs will be showed:
            html.B(
                children='The article must be in English.'
            ),

            dcc.Input(
                id="input_url",
                type="url",
                placeholder="Source URL",
                required=True,
                style=dict(
                    width='100%'
                )
            )
        ]),

        # Radiobuttons for choosing parser:
        html.Div([
            html.Div('Parser:'),

            dcc.RadioItems(
                id='radiobuttons-parser',
                options=[
                    {'label': "lxml: newspaper3k's default parser", 'value': 'lxml'},
                    {'label': "html.parser: Python's default parser",
                    'value': 'html.parser'},
                    {'label': 'html5lib: Extremely lenient but quite slow',
                    'value': 'html5lib'},
                ],
                value='lxml'
            )
        ]),

        # Button to extract text from the give url:
        html.Button(
            id='extract-button-state',
            n_clicks=0,
            children='Extract',
            style=dict(
                width='100%'
            )
        ),

        # Div to debug:
        html.Div(id='output-state-extract')
    ]
)



# 2nd column:
col_2 = html.Div(
    className='column-right',
    children=[
        # Text area for the extracted text from the URL:
        html.Div('Extracted text:'),

        dcc.Textarea(
            id='textarea-processed-url',
            className='extracted-text',
            value='Textarea content initialized\nwith multiple lines of text',
            persistence=True,
            readOnly=True,
        )]
)



# Input question container:
input_question_container = html.Div(
    children=[
        html.Div(
            style={'margin-bottom': '10px'},
            children=[
                html.Div('Question:'),

                dcc.Input(
                    id="input-question",
                    type='text',
                    placeholder="Please enter your question.",
                    style=dict(
                        width='100%',
                    )
                )
            ]
        ),

        # Checkbutton for filtering numbers:
        dcc.Checklist(
            id='checkbutton',
            options=[
                {'label': 'Filter numbers', 'value': '1'},
            ],
            value=['1']
        ),
    ]
)
    


# Submit button container:
submit_button_container = html.Div(
    children=[
        html.Div(
            className='center',
            children=[
                html.Button(
                    id='submit-button-state',
                    className='submit-button',
                    n_clicks=0,
                    children='Submit')
            ],
            style=dict(
                margin='20px'
            )
        ),

        # Div to debug:
        html.Div(id='output-state-submit')
    ]
)




# ------------------------------ FINAL LAYOUT ------------------------------
layout = html.Div(
    className='main',
    children=[
        html.H1(
            children='T5 Text Extraction Demo',
            style={'textAlign': 'center'}
        ),

        html.Div(
            className="row",
            children=[
                col_1,
                col_2
            ]
        ),

        # Horizontal separator:
        html.Hr(),

        input_question_container,

        submit_button_container
    ]
)






# ------------------------------ CALLBACKS ------------------------------

# Callback for when the Extract button has been pressed:
@app.callback(
    [
        Output('output-state-extract', 'children'),
        Output('textarea-processed-url', 'value')
    ],
    [
        Input('extract-button-state', 'n_clicks')
    ],
    [
        State('input_url', 'value'),
        State('radiobuttons-parser', 'value')
    ]
)
def update_output_extract_button(n_clicks, url, parser):
    children = ''

    # Web scrapping
    if url is None:
        return children, ''

    else:
        regex_url = r"https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)"
        if re.match(regex_url, url) is None:
            children += '\nIncorrect url!'
            return children, ''

        else:
            article = Article(url=url, language='en')

            article.download()

            article.parse()
            title = article.title
            


            article.nlp()
            keywords = article.keywords

            if parser=='lxml':
                extracted_txt = article.text
            
            else:
                resp = requests.get(url)
                html_doc = resp.text
                soup = BeautifulSoup(html_doc, 'html.parser')
                extracted_txt = re.sub(r'(\n| )+', ' ', soup.text)
            
            children += f'Title: {title}, keywords: {keywords}, parser: {parser}'

            return children, extracted_txt



# Callback for when the Submit button has been pressed:
@app.callback(
    Output('output-state-submit', 'children'),
    [
        Input('submit-button-state', 'n_clicks')
    ],
    [
        State('textarea-processed-url', 'value'),
        State('input-question', 'value'),
        State('checkbutton', 'value')
    ]
)
def update_output_extract_button(n_clicks, processed_txt, question, checkbutton_value):
    # Question answering:
    if n_clicks >= 1:
        if len(processed_txt) == 0:
            return 'Please enter a proper URL.'
        
        elif question is None:
            return 'Please enter a question.'
        
        else:
            answer, paragraph, prob = question_answering(
                query=question, text=processed_txt, filter_numbers=checkbutton_value)

            children = [
                html.P(f'Asked question: "{question}"'),
                html.P(f'Answer: {answer}'),
                html.P(f'Paragraph: {paragraph}'),
                html.P(f'Probability: {prob}')
            ]
            return children

    else:
        return ''



# ------------------------------ LAYOUT CONTAINERS ------------------------------ # The main page will be divided in two columns. # We'll define them right away. # 1st column: # Where the content of the tabs will be showed: # Radiobuttons for choosing parser: # Button to extract text from the give url: # Div to debug: # 2nd column: # Text area for the extracted text from the URL: # Input question container: # Checkbutton for filtering numbers: # Submit button container: # Div to debug: # ------------------------------ FINAL LAYOUT ------------------------------ # Horizontal separator: # ------------------------------ CALLBACKS ------------------------------ # Callback for when the Extract button has been pressed: # Web scrapping #=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)" # Callback for when the Submit button has been pressed: # Question answering: