import logging
import os
import sqlite3
from datetime import datetime
from functools import wraps

from authlib.integrations.flask_client import OAuth
from dotenv import load_dotenv
from flask import Flask, jsonify, redirect, render_template, request, session, url_for
from flask_wtf.csrf import CSRFProtect

from flask_session import Session

# Import the init_db function from init_db.py
from init_db import init_db

# Load environment variables
load_dotenv()

# Initialize Flask app
app = Flask(__name__)
csrf = CSRFProtect(app)

# Configuration
app.secret_key = os.getenv('SECRET_KEY')
app.config['GOOGLE_ID'] = os.getenv('GOOGLE_ID')
app.config['GOOGLE_SECRET'] = os.getenv('GOOGLE_SECRET')
app.config['SESSION_TYPE'] = 'filesystem'
app.config['SESSION_PERMANENT'] = False
app.config['SESSION_COOKIE_SECURE'] = True
app.config['PERMANENT_SESSION_LIFETIME'] = 3600  # 1 hour
Session(app)

# Initialize the database at startup
with app.app_context():
    init_db()

# Set up logging
logging.basicConfig(level=logging.INFO)

# OAuth configuration
oauth = OAuth(app)
google = oauth.register(
    name='google',
    client_id=app.config['GOOGLE_ID'],
    client_secret=app.config['GOOGLE_SECRET'],
    server_metadata_url='https://accounts.google.com/.well-known/openid-configuration',
    client_kwargs={'scope': 'openid email profile'}
)

# Database helper function
def get_db():
    conn = sqlite3.connect('tasks.db')
    conn.row_factory = sqlite3.Row  # Easier to work with dict-like rows
    return conn

# Decorator for login-required routes
def login_required(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if 'user' not in session:
            return redirect(url_for('login'))
        return f(*args, **kwargs)
    return decorated_function

# Routes
@app.route('/')
def home():
    return render_template('home.html')

@app.route('/login')
def login():
    redirect_uri = url_for('authorized', _external=True, _scheme=request.scheme)
    return google.authorize_redirect(redirect_uri)

@app.route('/login/authorized')
def authorized():
    try:
        token = google.authorize_access_token()
        user_info = google.get('https://www.googleapis.com/oauth2/v1/userinfo').json()
        session['user'] = user_info
        return redirect(url_for('profile'))
    except Exception as e:
        app.logger.error(f"Authorization failed: {e}")
        return f"Authorization failed: {str(e)}"

@app.route('/profile')
@login_required
def profile():
    user_info = session.get('user')
    return render_template('profile.html', user_info=user_info)

@app.route('/update_profile', methods=['POST'])
@login_required
def update_profile():
    data = request.get_json()
    user_info = session['user']

    for key, value in data.items():
        if key in user_info:
            user_info[key] = value

    session['user'] = user_info
    return jsonify({'status': 'success', 'message': 'Profile updated successfully'})

@app.route('/task')
@login_required
def task():
    user_email = session.get("user")["email"]

    conn = get_db()
    cursor = conn.cursor()
    cursor.execute("""
        SELECT id, task_name, priority, assignee, description,
               task_start_date, task_end_date, updated_date, updated_count
        FROM tasks WHERE email = ?
    """, (user_email,))
    tasks = cursor.fetchall()
    conn.close()

    return render_template('task.html', tasks=tasks)

@app.route('/add_task', methods=['POST'])
@login_required
def add_task():
    user_email = session.get("user")["email"]
    task_data = {
        'task_name': request.form['task_name'],
        'priority': request.form['priority'],
        'assignee': request.form['assignee'],
        'description': request.form['description'],
        'task_start_date': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
        'task_end_date': request.form['task_end_date'],
        'updated_count': 0
    }

    conn = get_db()
    cursor = conn.cursor()
    cursor.execute('''
        INSERT INTO tasks (email, task_name, priority, assignee, description, task_start_date, task_end_date)
        VALUES (?, ?, ?, ?, ?, ?, ?)
    ''', (user_email, task_data['task_name'], task_data['priority'], task_data['assignee'],
          task_data['description'], task_data['task_start_date'], task_data['task_end_date']))
    conn.commit()
    task_data['id'] = cursor.lastrowid
    conn.close()

    return jsonify({'status': 'success', 'task': task_data})

@app.route('/update_task', methods=['POST'])
@login_required
def update_task():
    task_data = {
        'id': request.form['task_id'],
        'task_name': request.form['task_name'],
        'priority': request.form['priority'],
        'assignee': request.form['assignee'],
        'description': request.form['description'],
        'task_start_date': request.form['task_start_date'],
        'task_end_date': request.form['task_end_date'],
        'updated_count': int(request.form['updated_count']) + 1,
        'updated_date': datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    }

    conn = get_db()
    cursor = conn.cursor()
    cursor.execute('''
        UPDATE tasks
        SET task_name = ?, priority = ?, assignee = ?, description = ?, 
            task_start_date = ?, task_end_date = ?, updated_date = ?, updated_count = ?
        WHERE id = ?
    ''', (task_data['task_name'], task_data['priority'], task_data['assignee'], task_data['description'],
          task_data['task_start_date'], task_data['task_end_date'], task_data['updated_date'], 
          task_data['updated_count'], task_data['id']))
    conn.commit()
    conn.close()

    return jsonify({'status': 'success', 'task': task_data})

@app.route('/delete_task', methods=['POST'])
@login_required
def delete_task():
    task_id = request.form['task_id']

    conn = get_db()
    cursor = conn.cursor()
    cursor.execute('DELETE FROM tasks WHERE id = ?', (task_id,))
    conn.commit()
    conn.close()

    return jsonify({'status': 'success', 'task_id': task_id})

@app.route('/logout')
def logout():
    session.clear()
    return redirect(url_for('home'))

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