from flask import Blueprint, request, jsonify, current_app
from flask_mail import Message
from app import mail
from datetime import timedelta
from werkzeug.security import check_password_hash
from app.models import User, Plak, SelectedPlak
from app.db import db
from datetime import datetime
import random
import smtplib
from email.mime.text import MIMEText
from app.models import Notification
from flask_cors import CORS
import traceback
import jwt


user_bp = Blueprint('user', __name__)
plak_bp = Blueprint('plak', __name__)


def after_request(response):
    response.headers.add('Access-Control-Allow-Origin', '*')
# Function to send email (simplified SMTP)
def send_verification_email(to_email, code):
    msg = MIMEText(f"Your verification code is: {code}")
    msg['Subject'] = 'EasyAligner Email Verification'
    msg['From'] = 'no-reply@easyaligner.com'
    msg['To'] = to_email

    try:
        with smtplib.SMTP('localhost') as server:
            server.sendmail(msg['From'], [to_email], msg.as_string())
    except Exception as e:
        print("Email sending failed:", e)

# User Registration
@user_bp.route('/register', methods=['POST'])
def register():
    try:
        data = request.get_json()
        required_fields = ['first_name', 'last_name', 'email', 'password', 'user_type']

        if not all(field in data and data[field] for field in required_fields):
            return jsonify({"msg": "Missing required fields"}), 400

        if User.query.filter_by(email=data['email']).first():
            return jsonify({"msg": "Email already exists"}), 409

        # Parse birthday
        birthday = None
        if data.get('birthday'):
            try:
                birthday = datetime.strptime(data['birthday'], '%Y-%m-%d')
            except ValueError:
                try:
                    birthday = datetime.strptime(data['birthday'], '%d.%m.%Y')
                except ValueError:
                    return jsonify({"msg": "Invalid birthday format. Use YYYY-MM-DD or DD.MM.YYYY"}), 400

        # Handle user_type conversion
        user_type_raw = data['user_type']
        if isinstance(user_type_raw, str) and user_type_raw.isdigit():
            user_type_raw = int(user_type_raw)

        user_type_map = {
            1: 'doctor',
            2: 'patient'
        }
        user_type_value = user_type_map.get(user_type_raw)
        if not user_type_value and user_type_raw in ['doctor', 'patient']:
            user_type_value = user_type_raw

        if not user_type_value:
            return jsonify({"msg": "Invalid user_type. Use 1, 2, 'doctor', or 'patient'."}), 400

        # Create user
        verification_code = str(random.randint(100000, 999999))
        user = User(
            first_name=data['first_name'].strip(),
            last_name=data['last_name'].strip(),
            email=data['email'].strip(),
            phone=data.get('phone'),
            city_id=data.get('city_id'),
            birthday=birthday,
            user_type=user_type_value,  # ✅ now always 'doctor' or 'patient'
            user_token=data.get('user_token'),
            verification_code=verification_code,
            is_verified=False
        )
        user.set_password(data['password'])

        db.session.add(user)
        db.session.commit()

        # Send email
        try:
            msg = Message(
                subject='EasyAligner E-posta Doğrulama Kodu',
                recipients=[user.email],
                body=f"Merhaba {user.first_name},\n\nDoğrulama kodunuz: {verification_code}\n\nTeşekkürler,\nPariwa Ekibi"
            )
            mail.send(msg)
        except Exception as email_error:
            print("Email send error:", email_error)

        return jsonify({
            "msg": "User registered successfully.",
            "email_sent": True
        }), 201

    except Exception as e:
        import traceback
        print("❌ Registration error:", str(e))
        print("Traceback:", traceback.format_exc())
        return jsonify({
            "msg": "An unexpected error occurred. Please try again later."
        }), 500

    
# Email verification route
@user_bp.route('/verify', methods=['POST'])
def verify_email():
    try:
        data = request.get_json()
        print(data)
        if not data:
            data = request.form  # Fallback for form-encoded data

        if not data:
            return jsonify({"status": "error", "msg": "No data provided"}), 400

        code = data.get('code')
        if not code:
            return jsonify({"status": "error", "msg": "Verification code is required"}), 400

        user = User.query.filter_by(verification_code=code).first()
        if not user:
            return jsonify({"status": "error", "msg": "Invalid verification code"}), 400

        if user.is_verified:
            return jsonify({"status": "error", "msg": "Email already verified"}), 400

        user.is_verified = True
        user.verification_code = None
        db.session.commit()

        return jsonify({
            "status": "success",
            "msg": "Email verified successfully"
        }), 200

    except Exception as e:
        db.session.rollback()
        return jsonify({
            "status": "error",
            "msg": "An error occurred during verification"
        }), 500


# User Login
@user_bp.route('/login', methods=['POST'])
def login():
    data = request.get_json()
    email = data.get('email')
    password = data.get('password')

    if not email or not password:
        return jsonify({"msg": "Email and password are required."}), 400

    user = User.query.filter_by(email=email).first()

    if not user:
        return jsonify({"msg": "User not found."}), 404

    if not user.is_verified:
        return jsonify({"msg": "Please verify your email first."}), 403

    if not check_password_hash(user.password_hash, password):
        return jsonify({"msg": "Incorrect password."}), 401

    # ✅ Generate JWT token
    token = jwt.encode(
        {
            'user_id': user.id,
            'exp': datetime.utcnow() + timedelta(hours=24)
        },
        current_app.config['SECRET_KEY'],
        algorithm='HS256'
    )

    return jsonify({
        "status": "success",
        "msg": "Login successful",
        "token": token,
        "user": {
            "id": user.id,
            "first_name": user.first_name,
            "last_name": user.last_name,
            "phone": user.phone,
            "birthday": user.birthday,
            "email": user.email,
            "user_type": user.user_type
        }
    }), 200

# fetch user data
@user_bp.route('/users/<int:user_id>', methods=['GET'])
def get_user(user_id):
    user = User.query.get(user_id)
    if not user:
        return jsonify({"msg": "User not found"}), 404

    return jsonify({
        "id": user.id,
        "first_name": user.first_name,
        "last_name": user.last_name,
        "email": user.email,
        "phone": user.phone,
        "city_id": user.city_id,
        "birthday": user.birthday.strftime('%Y-%m-%d') if user.birthday else None
    }), 200
# Fprgot password
@user_bp.route('/forgot-password', methods=['POST'])
def forgot_password():
    data = request.get_json()
    email = data.get('email')

    user = User.query.filter_by(email=email).first()
    if not user:
        return jsonify({"msg": "User not found"}), 404

    reset_code = str(random.randint(100000, 999999))
    user.reset_code = reset_code
    user.reset_code_expiration = datetime.utcnow() + timedelta(minutes=60)

    db.session.commit()

    msg = Message(
        subject='Şifre Sıfırlama Kodu',
        recipients=[user.email],
        body=f"Merhaba {user.first_name},\n\nŞifre sıfırlama kodunuz: {reset_code}\nKod 10 dakika boyunca geçerlidir.\n\nPariwa Ekibi"
    )
    mail.send(msg)

    return jsonify({"msg": "Reset code sent to your email."}), 200

# Reset Password
@user_bp.route('/reset-password', methods=['POST'])
def reset_password():
    data = request.get_json()
    email = data.get('email')
    code = data.get('code')
    new_password = data.get('new_password')

    user = User.query.filter_by(email=email).first()
    if not user:
        return jsonify({"msg": "User not found"}), 404

    if user.reset_code != code or datetime.utcnow() > user.reset_code_expiration:
        return jsonify({"msg": "Invalid or expired reset code"}), 400

    user.set_password(new_password)
    user.reset_code = None
    user.reset_code_expiration = None
    db.session.commit()

    return jsonify({"msg": "Password reset successful"}), 200

# Update user data 
@user_bp.route('/<int:id>/update', methods=['PUT'])
def update_user(id):
    data = request.get_json()
    user = User.query.get(id)

    if not user:
        return jsonify({"msg": "User not found"}), 404

    # Update basic fields
    user.first_name = data.get('first_name', user.first_name)
    user.last_name = data.get('last_name', user.last_name)
    user.phone = data.get('phone', user.phone)
    user.city_id = data.get('city_id', user.city_id)
    if data.get('birthday'):
        user.birthday = datetime.strptime(data['birthday'], '%Y-%m-%d')

    # ✅ Update password if provided
    if data.get('new_password'):
        user.set_password(data['new_password'])

    user.updated_at = datetime.utcnow()
    db.session.commit()

    return jsonify({
        "msg": "User updated successfully",
        "user": {
            "id": user.id,
            "first_name": user.first_name,
            "last_name": user.last_name,
            "email": user.email,
            "phone": user.phone,
            "city_id": user.city_id,
            "birthday": user.birthday.strftime('%Y-%m-%d') if user.birthday else None
        }
    }), 200





# Get selected plak by patient
@plak_bp.route('/plaks/selected/<int:patient_id>', methods=['GET'])
def get_selected_plak(patient_id):
    selection = SelectedPlak.query.filter_by(patient_id=patient_id).first()
    if not selection:
        return jsonify({"msg": "No plak selected"}), 404

    plak = selection.plak
    return jsonify({
        "id": plak.id,
        "title": plak.title,
        "description": plak.description,
        "image_url": plak.image_url
    })

## Create Notification
@user_bp.route('/notifications', methods=['POST'])
def create_notification():
    data = request.get_json()
    notification = Notification(
        user_id=data['user_id'],
        title=data['title'],
        message=data['message']
    )
    db.session.add(notification)
    db.session.commit()
    return jsonify({"msg": "Notification created"}), 201

# Get Notifications for User
@user_bp.route('/notifications/<int:user_id>', methods=['GET'])
def get_notifications(user_id):
    notifications = Notification.query.filter_by(user_id=user_id).order_by(Notification.created_at.desc()).all()
    return jsonify([
        {
            "id": n.id,
            "title": n.title,
            "message": n.message,
            "is_read": n.is_read,
            "created_at": n.created_at.strftime("%Y-%m-%d %H:%M:%S")
        } for n in notifications
    ]), 200

# Mark as read 
@user_bp.route('/notifications/<int:id>/read', methods=['PUT'])
def mark_as_read(id):
    notification = Notification.query.get_or_404(id)
    notification.is_read = True
    db.session.commit()
    return jsonify({"msg": "Marked as read"}), 200

# Create Mock notifications
@user_bp.route('/notifications/mock/<int:user_id>', methods=['POST'])
def create_mock_notifications(user_id):
    mock_data = [
        {"title": "Easyaligner", "message": "Yeni plaklarımız mevcut, ilk inceleyen sen ol"},
        {"title": "Tedavi Süreci", "message": "Bugün tedavi sürecinizi fotoğraflamayı unutmayın."},
        {"title": "Doktorunuzdan Mesaj", "message": "Tedavi planınız hakkında yeni öneriler var."},
        {"title": "Fotoğraf Onaylandı", "message": "Yüklediğiniz tedavi fotoğrafı doktor tarafından onaylandı."}
    ]

    for item in mock_data:
        notification = Notification(user_id=user_id, title=item["title"], message=item["message"])
        db.session.add(notification)

    db.session.commit()
    return jsonify({"msg": "Mock notifications created."}), 201
