from flask import Flask, render_template, request, redirect, url_for
import uuid
import csv
import os
import smtplib
from email.message import EmailMessage
from wtforms import Form, StringField, SelectField, RadioField, TextAreaField,  BooleanField, validators
from wtforms.fields.html5 import EmailField
import importlib

app = Flask(__name__)
app.jinja_env.trim_blocks = True
app.jinja_env.lstrip_blocks = True

datafile = "data.csv"
solutionfile = "solutions.csv"
mailfile = "mail.csv"

def check_input(form, field):
    if field.data == 'default':
        raise validators.ValidationError('Bitte wähle eine Option aus')


class QuestionForm(Form):
    computers = [('default', 'Bitte auswählen'), ('hal', 'HAL 9000 (2001: Odyssee im Weltraum)'), ('deepthought', 'Deep Thought (Hitchhiker\'s Guide)'), ('neuromancer', 'Neuromancer (Neuromancer)'), ('samantha', 'Samatha (Her)'), ('tars', 'TARS und CASE (Interstellar)')]
    computer = SelectField(u'Fiktionaler Lieblingscomputer', choices=computers, validators=[validators.InputRequired(), check_input])
    statuses = [('default', 'Bitte auswählen'), ('200', '200 OK'), ('300', '300 Multiple Choices'), ('301', '301 Moved Permanently'), ('402', '402 Payment Required'), ('404', '404 (Sleep) Not Found'), ('408', '408 Request Timeout'), ('418', '418 I am a teapot'), ('450', '450 Blocked by Windows Parental Controls'), ('451', '451 Unavailable For Legal Reasons'), ('502', '502 Bad Gateway (Internetkurort)')]
    status = SelectField(u'Welcher HTTP-Statuscode trifft am häufigsten auf dich zu?', choices=statuses, validators=[validators.InputRequired(), check_input])
    vegetables = [('default', 'Bitte auswählen'), ('karotte', '🥕'), ('broccoli','🥦'), ('aubergine', '🍆'), ('kartoffel', '🥔'), ('bretzel', '🥨'), ('tomate', '🍅'), ('chili', '🌶️')]
    vegetable  = SelectField(u'Lieblingsgemüse', choices=vegetables, validators=[validators.InputRequired(), check_input])
    spirit_animals = [('default', 'Bitte auswählen'), ('feuer', 'Feuerfuchs'), ('wasser', 'Wasserhahn'), ('erde', 'Erdferkel'), ('luft', 'Luftschlange')]
    spirit_animal = SelectField(u'Spirit Animal', choices=spirit_animals, validators=[validators.InputRequired(), check_input])
    operating_systems = [('default', 'Bitte auswählen'), ('windows', 'Windows'), ('mac', 'Mac'), ('linux', 'Linux'), ('kaffee', 'Kaffee'), ('glados', 'GLaDOS')]
    operating_system = SelectField(u'Bevorzugtes Betriebssystem', choices=operating_systems, validators=[validators.InputRequired(), check_input])
    check = BooleanField('Bitte nicht ankreuzen')
    email = EmailField('Email-Adresse')


class SolutionForm(Form):
    user_id = StringField('id', [validators.InputRequired()])
    choices = [('computer', 'Fiktionaler Lieblingscomputer'), ('status', 'HTTP-Statuscode'), ('vegetable', 'Lieblingsgemüse'), ('spirit_animal', 'Spirit Animal'), ('operating system', 'Betriebssystem'), ('check', 'Bitte nicht ankreuzen')]
    question = RadioField(u'Welche Frage ist ausschlaggebend für die Hauszuordnung?', choices=choices, validators=[validators.InputRequired(message='Bitte ankreuzen'),])
    solution_text = TextAreaField(u'Textfeld')

def create_used_id_list():
    data = list()
    if not os.path.exists(datafile):
        open(datafile, "a").close()

    with open(datafile, "r") as f:
        reader = csv.reader(f)
        for line in reader:
            data.append(line[0])
    return data

def check_id(form, field):
    used_ids = create_used_id_list()
    if field.data not in used_ids:
        raise validators.ValidationError('Leider keine gültige ID')

class AnswerForm(Form):
    user_id = StringField('Id', [validators.InputRequired(), check_id])



@app.route('/')
def index():
    return render_template('index.html', title='Sortierhut') 

@app.route('/questions', methods=['GET', 'POST'])
def questions():
    form = QuestionForm(request.form)
    houses = dict()
    houses[0] = 'knuth'
    houses[1] = 'lovelace'
    houses[2] = 'turing'
    houses[4] = 'hopper'
    houses[8] = 'lamarr'

    if request.method == 'POST' and form.validate():
        with open(datafile, "a", newline='') as f:
            new_row = list()
            new_id = generate_id()
            new_row.append(new_id)
            for item in request.form:
                new_row.append(request.form[item])

            if len(new_row) == 6:
                new_row.append('n')
            
            magical_house_number = int(new_row[2]) % 10
            new_row.append(houses[magical_house_number])
            writer = csv.writer(f)
            writer.writerow(new_row)

            return redirect(url_for('result', user_id=new_id))
    return render_template('questions.html', form=form, title='Sortierhut')

@app.route('/solution', methods=['GET', 'POST'])
def solution():
    form = SolutionForm(request.form)
    if request.method == 'POST' and form.validate():
        with open(solutionfile, "a", newline='') as f:
            solution_list = list()
            for item in request.form:
                solution_list.append(request.form[item])
            writer = csv.writer(f)
            writer.writerow(solution_list)
            return redirect(url_for('thanks'))
    return render_template('solution.html', form=form, title='Sortierhut') 

@app.route('/result<user_id>')
def result(user_id):
    return render_template('result.html', title='Sortierhut', id=user_id) 

def convert_csv_to_list_of_lists(csv_file):
    list_of_lists = list()

    if not os.path.exists(csv_file):
        open(csv_file, 'a').close()

    with open(csv_file, 'r', newline='') as f:
        reader = csv.reader(f)
        for line in reader:
            list_of_lists.append(line)
    return list_of_lists

@app.route('/admint_form')
def admin_form():
    file_data = convert_csv_to_list_of_lists(datafile)
    return render_template('admin_form.html', title='Sortierhut', text='Hallo, Admin Fooboar', file_data=file_data) 

@app.route('/admint_solution')
def admin_solution():
    file_data = convert_csv_to_list_of_lists(solutionfile)
    return render_template('admin_solution.html', title='Sortierhut', file_data=file_data)

@app.route('/answers', methods=['GET', 'POST'])
def answers():
    form = AnswerForm(request.form)
    if request.method == 'POST' and form.validate():
        ident = request.form['user_id'] 
        return redirect(url_for('view_answers', user_id=ident))
    return render_template('answers.html', form=form, title='Sortierhut') 

@app.route('/view_answers<user_id>')
def view_answers(user_id):
    user_row = list()
    with open(datafile, "r", newline='') as f:
        reader = csv.reader(f)
        for line in reader:
            if line[0] == user_id:
                user_row = line
                break
    return render_template('view_answers.html', title='Sortierhut', user_id=user_id, user_row=user_row)

@app.route('/thanks')
def thanks():
    return render_template('thanks.html', title='Sortierhut')

@app.route('/patrons')
def patrons():
    return render_template('patrons.html', title='Sortierhut')

def generate_id():
    data = create_used_id_list()
    # best loop ever
    while True:
        new_id = str(uuid.uuid1()).split("-")[0]

        if new_id in data:
            break
        else:
            return new_id
