import streamlit as st
from flask_sqlalchemy import SQLAlchemy
from flask_bcrypt import Bcrypt
from flask_mail import Mail, Message
import openai
from flask import Flask

# Streamlit Configuration
st.set_page_config(page_title="Sociocracy App")

# Flask Configuration for Database and Mail
app = Flask(__name__)
app.secret_key = 's3cr3t'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///sociocracy.db'
db = SQLAlchemy(app)
bcrypt = Bcrypt(app)

# Configuring Flask-Mail
app.config['MAIL_SERVER'] = 'smtp.example.com'
app.config['MAIL_PORT'] = 587
app.config['MAIL_USERNAME'] = 'your_email@example.com'
app.config['MAIL_PASSWORD'] = 'your_password'
app.config['MAIL_USE_TLS'] = True
app.config['MAIL_USE_SSL'] = False
mail = Mail(app)

# User model
class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(50), unique=True, nullable=False)
    password = db.Column(db.String(100), nullable=False)
    email = db.Column(db.String(100), unique=True, nullable=False)

# Issue model
class Issue(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(100), nullable=False)
    description = db.Column(db.Text, nullable=False)
    created_by = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)

# Solution model
class Solution(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    content = db.Column(db.Text, nullable=False)
    issue_id = db.Column(db.Integer, db.ForeignKey('issue.id'), nullable=False)
    created_by = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)

# Collaborator model
class Collaborator(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    issue_id = db.Column(db.Integer, db.ForeignKey('issue.id'), nullable=False)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)

# Streamlit Pages
st.sidebar.title("Navigation")
page = st.sidebar.radio("Go to", ["Register", "Login", "Dashboard", "Create Issue", "Invite Collaborators", "Submit Solution", "Decide", "Settings"])

# Header for Notifications and User Info
if 'user_id' in st.session_state and st.session_state['user_id'] is not None:
    with app.app_context():
        user = User.query.get(st.session_state['user_id'])
        if user:
            st.sidebar.markdown(f"**Hello, {user.username}**")
            notification_icon = "🔔"
            if Issue.query.join(Collaborator).filter(Collaborator.user_id == user.id).count() > 0:
                notification_icon = "🔔 (New)"
            st.sidebar.write(f"[{notification_icon} Notifications](#)")
            st.sidebar.write("[⚙️ Settings](#)")

# Register Page
def register():
    st.title("Register")
    username = st.text_input("Username")
    email = st.text_input("Email")
    password = st.text_input("Password", type="password")
    if st.button("Register"):
        if username and email and password:
            with app.app_context():
                hashed_pw = bcrypt.generate_password_hash(password).decode('utf-8')
                new_user = User(username=username, email=email, password=hashed_pw)
                db.session.add(new_user)
                db.session.commit()
                st.success("Registration successful! Please check your email for further instructions.")

                # Send registration email
                msg = Message('Welcome to Sociocracy App', sender='your_email@example.com', recipients=[email])
                msg.body = "Thank you for registering. You can now log in and start collaborating."
                mail.send(msg)
        else:
            st.error("Please fill all fields.")

# Login Page
def login():
    st.title("Login")
    username = st.text_input("Username")
    password = st.text_input("Password", type="password")
    if st.button("Login"):
        with app.app_context():
            user = User.query.filter_by(username=username).first()
            if user and bcrypt.check_password_hash(user.password, password):
                st.session_state['user_id'] = user.id
                st.success("Login successful!")
            else:
                st.error("Invalid username or password.")

# Dashboard Page
def dashboard():
    if 'user_id' not in st.session_state:
        st.warning("You need to log in first.")
        return

    st.title("Dashboard")
    user_id = st.session_state['user_id']
    with app.app_context():
        user = User.query.get(user_id)
        st.header(f"Hello, {user.username}")

        user_issues = Issue.query.filter_by(created_by=user_id).all()
        collaboration_issues = Issue.query.join(Collaborator).filter(Collaborator.user_id == user_id).all()

    st.header("Your Issues")
    for issue in user_issues:
        st.write(f"Title: {issue.title}")
        if st.button(f"Submit Solution for {issue.title}"):
            submit_solution(issue.id)
        if st.button(f"Decide on {issue.title}"):
            decide(issue.id)

    st.header("Issues You Are Collaborating On")
    for issue in collaboration_issues:
        st.write(f"Title: {issue.title}")
        if st.button(f"Submit Solution for {issue.title}"):
            submit_solution(issue.id)
        if st.button(f"Decide on {issue.title}"):
            decide(issue.id)

# Create Issue Page
def create_issue():
    if 'user_id' not in st.session_state:
        st.warning("You need to log in first.")
        return

    st.title("Create Issue")
    title = st.text_input("Issue Title")
    description = st.text_area("Issue Description")
    if st.button("Create Issue"):
        with app.app_context():
            new_issue = Issue(title=title, description=description, created_by=st.session_state['user_id'])
            db.session.add(new_issue)
            db.session.commit()
        st.success("Issue created successfully!")

# Invite Collaborators Page
def invite_collaborators():
    if 'user_id' not in st.session_state:
        st.warning("You need to log in first.")
        return

    st.title("Invite Collaborators")
    issue_id = st.number_input("Issue ID", min_value=1, step=1)
    emails = st.text_input("Collaborator Emails (comma-separated)")
    if st.button("Send Invites"):
        with app.app_context():
            issue = Issue.query.get(issue_id)
            if issue:
                for email in emails.split(','):
                    email = email.strip()
                    user = User.query.filter_by(email=email).first()
                    if user:
                        new_collaborator = Collaborator(issue_id=issue_id, user_id=user.id)
                        db.session.add(new_collaborator)
                    msg = Message('Collaboration Invite', sender='your_email@example.com', recipients=[email])
                    msg.body = f"You have been invited to collaborate on the issue: {issue.title}."
                    mail.send(msg)
                db.session.commit()
                st.success("Invitations sent successfully!")
            else:
                st.error("Issue not found.")

# Submit Solution Page
def submit_solution(issue_id):
    if 'user_id' not in st.session_state:
        st.warning("You need to log in first.")
        return

    st.title(f"Submit Solution for Issue {issue_id}")
    solution_content = st.text_area("Your Solution")
    if st.button("Submit Solution"):
        with app.app_context():
            new_solution = Solution(content=solution_content, issue_id=issue_id, created_by=st.session_state['user_id'])
            db.session.add(new_solution)
            db.session.commit()
        st.success("Solution submitted successfully!")

# Decide Page
def decide(issue_id):
    with app.app_context():
        issue = Issue.query.get(issue_id)
        solutions = Solution.query.filter_by(issue_id=issue_id).all()
    
    if issue:
        st.title(f"Decide on Issue: {issue.title}")
        for solution in solutions:
            st.write(f"- {solution.content}")

        if st.button("Get AI Decision"):
            openai.api_key = 'your_openai_api_key'
            prompt = f"Given the following solutions for the issue '{issue.title}', which one is the most socio-democratic decision?\n"
            for solution in solutions:
                prompt += f"- {solution.content}\n"
            prompt += "Please consider socio-democratic values and provide a summary on the best decision."

            response = openai.ChatCompletion.create(
                model="gpt-3.5-turbo",
                messages=[
                    {"role": "system", "content": "You are an assistant helping to make socio-democratic decisions."},
                    {"role": "user", "content": prompt}
                ],
                max_tokens=150
            )
            decision = response.choices[0].message['content'].strip()
            st.write(f"AI Decision: {decision}")

# Settings Page
def settings():
    if 'user_id' not in st.session_state:
        st.warning("You need to log in first.")
        return

    st.title("Settings")
    st.write("Update your general information here.")
    # Add settings fields as needed

# Main Flow
if 'user_id' not in st.session_state:
    st.session_state['user_id'] = None

if page == "Register":
    register()
elif page == "Login":
    login()
elif page == "Dashboard":
    dashboard()
elif page == "Create Issue":
    create_issue()
elif page == "Invite Collaborators":
    invite_collaborators()
elif page == "Submit Solution":
    issue_id = st.number_input("Issue ID", min_value=1, step=1)
    submit_solution(issue_id)
elif page == "Decide":
    issue_id = st.number_input("Issue ID", min_value=1, step=1)
    decide(issue_id)
elif page == "Settings":
    settings()