from flask import Flask, render_template_string, request, url_for, redirect
from werkzeug.security import generate_password_hash, check_password_hash
from flask_sqlalchemy import SQLAlchemy
import os
from werkzeug.utils import secure_filename
from urllib.parse import quote_plus

app = Flask(__name__)

db_password = quote_plus('**12345#tunasmuda')

app.config['SQLALCHEMY_DATABASE_URI'] = f'mysql+pymysql://tunasmud_python:{db_password}@localhost:3306/tunasmud_python'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['UPLOAD_FOLDER'] = 'static/uploads'

if not os.path.exists(app.config['UPLOAD_FOLDER']):
    os.makedirs(app.config['UPLOAD_FOLDER'])

db = SQLAlchemy(app)

# ================= DATABASE =================
class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(100), unique=True, nullable=False)
    password = db.Column(db.String(200), nullable=False)
    email = db.Column(db.String(200))
    phone = db.Column(db.String(20))
    fullname = db.Column(db.String(200)) 
    profile_pic = db.Column(db.String(200))
    reset_token = db.Column(db.String(200)) 

with app.app_context():
    try:
        db.create_all()
        print("✅ MySQL connected successfully")
    except Exception as e:
        print("❌ Connection error:", e)


# ================= LOGIN PAGE =================
login_page = """
<!DOCTYPE html>
<html>
<head>
<title>Login</title>

<style>
body {
    font-family: Arial;
    background:#e6f0ff;
    display:flex;
    justify-content:center;
    align-items:center;
    height:100vh;
}

/* CONTAINER */
.container {
    background:#fff;
    padding:30px;
    border-radius:10px;
    width:350px;
    text-align:center;
    box-shadow:0 4px 10px rgba(0,0,0,0.2);
}

/* INPUT */
input{
    width:100%;
    padding:10px;
    margin-top:8px;
    margin-bottom:10px;
    border-radius:5px;
    border:1px solid #ccc;
    box-sizing:border-box;
}

/* PASSWORD BOX */
.password-container{
    position:relative;
}

/* EYE ICON INSIDE FIELD */
.toggle-password{
    position:absolute;
    right:10px;
    top:50%;
    transform:translateY(-50%);
    width:20px;
    cursor:pointer;
}

/* BUTTON */
button{
    width:100%;
    padding:10px;
    margin-top:20px;
    background:#0052cc;
    color:white;
    border:none;
    border-radius:5px;
}

/* LINKS */
.links{
    text-align:center;
    margin-top:10px;
}

.error{
    color:red;
}
</style>
</head>

<body>

<div class="container">
<h2>Login</h2>

{% if error %}
<div class="error">{{ error }}</div>
{% endif %}

<form method="POST">

<input type="text" name="username" placeholder="Username" required>

<div class="password-container">
    <input type="password" name="password" id="password" placeholder="Password" required>

    <img src="{{ url_for('static', filename='close_eyes.jpg') }}"
         id="eye"
         class="toggle-password"
         onclick="toggle()">
</div>

<button type="submit">Login</button>
</form>

<div class="links">
Don't have an account?
<a href="{{ url_for('register') }}">Register</a><br><br>
<a href="{{ url_for('forgot_password') }}">Forgot Password?</a>
</div>

</div>

<script>
function toggle(){
    var p = document.getElementById("password");
    var eye = document.getElementById("eye");

    if(p.type === "password"){
        p.type = "text";
        eye.src = "{{ url_for('static', filename='open_eyes.jpg') }}";
    } else {
        p.type = "password";
        eye.src = "{{ url_for('static', filename='close_eyes.jpg') }}";
    }
}
</script>

</body>
</html>
"""


register_page = """
<!DOCTYPE html>
<html>
<head>
<title>Register</title>

<style>
body {
    font-family: Arial;
    background:#e6f0ff;
    display:flex;
    justify-content:center;
    align-items:center;
    height:100vh;
}

.container {
    background:#fff;
    padding:30px;
    border-radius:10px;
    width:350px;
    text-align:center;
    box-shadow:0 4px 10px rgba(0,0,0,0.2);
}

/* ===== INPUT STYLE (FIXED LIKE RESET PAGE) ===== */
input{
    width:100%;
    padding:10px;
    margin-top:8px;
    margin-bottom:10px;
    border-radius:5px;
    border:1px solid #ccc;
    box-sizing:border-box;
}

/* BUTTON */
button{
    width:100%;
    padding:10px;
    margin-top:20px;
    background:#0052cc;
    color:white;
    border:none;
    border-radius:5px;
}

button:disabled{
    background:#999;
}

.links{
    text-align:center;
    margin-top:10px;
}

.error{
    color:red;
    text-align:center;
}

.success{
    color:green;
    text-align:center;
}

/* PASSWORD FIELD */
.password-container{
    position:relative;
}

.toggle-password{
    position:absolute;
    right:10px;
    top:50%;
    transform:translateY(-50%);
    width:20px;
    cursor:pointer;
}

/* CHECKLIST */
.checklist {
    font-size:12px;
    margin-top:10px;
    padding-left:0;
    text-align:left;
}

.checklist li {
    list-style:none;
    display:flex;
    align-items:center;
    gap:6px;
    margin-bottom:3px;
    color:#999;
}

.checklist li.valid {
    color:green;
}

.checklist li input{
    width:14px;
    height:14px;
    pointer-events:none;
}
</style>

</head>

<body>

<div class="container">

<h2>Register</h2>

{% if error %}<div class="error">{{ error }}</div>{% endif %}
{% if success %}<div class="success">{{ success }}</div>{% endif %}

<form method="POST">

<input type="text" name="fullname" placeholder="Full Name" value="{{ fullname }}" required>
<input type="text" name="username" placeholder="Username" value="{{ username }}" required>
<input type="email" name="email" placeholder="Email" value="{{ email }}" required>

<div class="password-container">
<input type="password" name="password" id="password"
value="{{ password }}" placeholder="Password (8+ characters)">
<img src="{{ url_for('static', filename='close_eyes.jpg') }}"
id="eye1" class="toggle-password"
onclick="toggle('password','eye1')">
</div>

<div class="password-container">
<input type="password" id="confirm_password" name="confirm_password"
value="{{ confirm_password }}" placeholder="Confirm Password">
<img src="{{ url_for('static', filename='close_eyes.jpg') }}"
id="eye2" class="toggle-password"
onclick="toggle('confirm_password','eye2')">
</div>

<ul class="checklist">
<li id="u"><input type="checkbox" disabled> At least 1 uppercase letter</li>
<li id="l"><input type="checkbox" disabled> At least 1 lowercase letter</li>
<li id="n"><input type="checkbox" disabled> At least 1 number</li>
<li id="s"><input type="checkbox" disabled> At least 1 special character</li>
</ul>

<button id="registerBtn" type="submit" disabled>Register</button>

</form>

<div class="links">
<a href="{{ url_for('login') }}">Back to Login</a>
</div>

</div>

<script>
function toggle(id,eye){
var p=document.getElementById(id);
var e=document.getElementById(eye);

if(p.type==="password"){
p.type="text";
e.src="{{ url_for('static', filename='open_eyes.jpg') }}";
}else{
p.type="password";
e.src="{{ url_for('static', filename='close_eyes.jpg') }}";
}
}

var p=document.getElementById("password");
var c=document.getElementById("confirm_password");
var btn=document.getElementById("registerBtn");

function check(){
var fullname = document.querySelector("input[name='fullname']").value;
var username = document.querySelector("input[name='username']").value;
var email = document.querySelector("input[name='email']").value;

var val=p.value;
var confirmVal=c.value;

var up = /[A-Z]/.test(val);
var lo = /[a-z]/.test(val);
var nu = /[0-9]/.test(val);
var sy = /[!@#$%^&*]/.test(val);

document.getElementById("u").className = up ? "valid" : "";
document.getElementById("u").querySelector("input").checked = up;

document.getElementById("l").className = lo ? "valid" : "";
document.getElementById("l").querySelector("input").checked = lo;

document.getElementById("n").className = nu ? "valid" : "";
document.getElementById("n").querySelector("input").checked = nu;

document.getElementById("s").className = sy ? "valid" : "";
document.getElementById("s").querySelector("input").checked = sy;

btn.disabled = !(fullname && username && email && val && confirmVal);
}

p.addEventListener("input",check);
c.addEventListener("input",check);
</script>

</body>
</html>
"""

# ================= HOME PAGE =================
home_page = """
<!DOCTYPE html>
<html>
<head>
<title>Home</title>
<style>
body { 
    font-family: Arial; 
    background:#e6f0ff; 
    display:flex; 
    justify-content:center; 
    align-items:center; 
    height:100vh;
}

.container { 
    background:#fff; 
    padding:30px; 
    border-radius:10px; 
    width:350px; 
    text-align:center; 
    box-shadow:0 4px 10px rgba(0,0,0,0.2);
}

.profile-pic {
    width:120px;
    height:120px;
    border-radius:50%;
    object-fit:cover;
    border:3px solid #0052cc;
    margin-bottom:15px;
    display:block;
    margin-left:auto;
    margin-right:auto;
}

h3 {
    color:#003366;
    margin-bottom:15px;
}

button {
    width:auto;
    padding:8px 14px;
    margin-top:15px;
    background:#fff;
    color:#0052cc;
    border:1px solid #0052cc;
    border-radius:20px;
    cursor:pointer;
}

button:hover {
    background:#e6f0ff;
}
</style>
</head>

<body>

<div class="container">

<img class="profile-pic"
     src="{{ url_for('static', filename='uploads/' + (user.profile_pic if user.profile_pic else 'default_profile.jpg')) }}"
     onerror="this.onerror=null;this.src='{{ url_for('static', filename='default_profile.jpg') }}';">

<h3>{{ username }}</h3>

<button onclick="window.location.href='{{ url_for('profile', username=username) }}'">
    Edit Profile
</button>

</div>

</body>
</html>
"""


# ================= PROFILE PAGE =================
profile_page = """
<!DOCTYPE html>
<html>
<head>
<title>Profile</title>

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css">

<style>
body {
    font-family: Arial;
    background:#e6f0ff;
    display:flex;
    justify-content:center;
    align-items:center;
    height:100vh;
}

.container {
    background:#fff;
    padding:30px;
    border-radius:10px;
    width:350px;
    text-align:center;
    box-shadow:0 4px 10px rgba(0,0,0,0.2);
}

.profile-pic {
    width:120px;
    height:120px;
    border-radius:50%;
    object-fit:cover;
    border:3px solid #0052cc;
    margin-bottom:10px;
}

h3 {
    color:#003366;
    margin-bottom:5px;
}

p {
    color:gray;
    margin-bottom:20px;
}

input {
    width:96%;
    padding:8px;
    margin:5px;
    border-radius:5px;
    border:1px solid #ccc;
}

button {
    margin-top:10px;
    padding:8px 14px;
    border-radius:20px;
    cursor:pointer;
}

.save {
    background:#00b894;
    color:white;
    border:none;
}

.back {
    background:#fff;
    color:#0052cc;
    border:1px solid #0052cc;
}

.back:hover {
    background:#e6f0ff;
}

.btn-row{
    display:flex;
    justify-content:center;
    gap:10px;
    margin-top:10px;
}

.btn-row button{
    width:120px;
}

label{
    display:block;
    text-align:left;
    margin-top:10px;
    margin-bottom:4px;
    font-size:12px;
    color:#333;
}

.form-group{
    width:100%;
    margin-bottom:12px;
    text-align:left;
}

.form-group label{
    display:block;
    font-size:13px;
    margin-bottom:5px;
    color:#333;
}

.form-group input{
    width:100%;
    padding:10px;
    border:1px solid #ccc;
    border-radius:6px;
    box-sizing:border-box;
}

</style>
</head>

<body>

<div class="container">

<div style="text-align:center;">

    <img class="profile-pic"
         src="{{ url_for('static', filename='uploads/' + (user.profile_pic if user.profile_pic else 'default_profile.jpg')) }}"
         onerror="this.src='{{ url_for('static', filename='default_profile.jpg') }}'">

    <form id="uploadForm" method="POST" enctype="multipart/form-data">

        <input type="file" id="fileInput" name="profile_pic"
               accept=".png,.jpg,.jpeg"
               style="display:none"
               onchange="document.getElementById('uploadForm').submit();">

       <div style="margin-top:1px; display:flex; justify-content:center; gap:5px;">

    <i class="fa-solid fa-camera"
   title="Upload Image"
   onclick="document.getElementById('fileInput').click();"
   style="
        font-size:13px;
        width:23px;
        height:23px;
        display:flex;
        align-items:center;
        justify-content:center;
        cursor:pointer;
        background:none;
        border-radius:50%;
        padding:4px;
        box-shadow:0 2px 5px rgba(0,0,0,0.2);
        color:#333;
   "></i>

    <i class="fa-solid fa-trash"
   title="Remove Image"
   onclick="removeProfilePic()"
   style="
        font-size:13px;
        width:23px;
        height:23px;
        display:flex;
        align-items:center;
        justify-content:center;
        cursor:pointer;
        background:white;
        border-radius:50%;
        padding:4px;
        box-shadow:0 2px 5px rgba(0,0,0,0.2);
        color:#ff3b30;
   ">
</i>

</div>

    </form>
</div>

<h3 style="margin-top:20px;">{{ username }}</h3>
<p>{{ email }}</p>

<form method="POST">

   <div class="form-group">
    <label>Full Name</label>
    <input type="text" name="fullname" value="{{ fullname }}">
</div>

<div class="form-group">
    <label>Username</label>
    <input type="text" name="username" value="{{ username }}" required>
</div>

<div class="form-group">
    <label>Email</label>
    <input type="email" name="email" value="{{ email }}" required>
</div>

<div class="form-group">
    <label>Phone Number</label>
    <input type="text" name="phone" value="{{ phone }}">
</div>

    <div class="btn-row">

        <button type="button" class="back"
            onclick="window.location.href='{{ url_for('home', username=username) }}'">
            Back
        </button>

        <button type="submit" class="save">Save</button>
        
    </div>

</form>

<script>
function removeProfilePic(){
    fetch("/remove-profile-pic?username={{ username }}", {
        method: "POST"
    })
    .then(() => location.reload());
}
</script>

</body>
</html>
"""


# ================= FORGOT =================
forgot_page = """
<!DOCTYPE html>
<html>
<head>
<title>Forgot Password</title>

<style>
body {
    font-family: Arial;
    background:#e6f0ff;
    display:flex;
    justify-content:center;
    align-items:center;
    height:100vh;
}

.container {
    background:#fff;
    padding:30px;
    border-radius:10px;
    width:350px;
    text-align:center;
    box-shadow:0 4px 10px rgba(0,0,0,0.2);
}

input{
    width:100%;
    padding:10px;
    margin-top:10px;
    margin-bottom:10px;
    border-radius:5px;
    border:1px solid #ccc;
    box-sizing:border-box;
}

button{
    width:100%;
    padding:10px;
    margin-top:15px;
    background:#0052cc;
    color:white;
    border:none;
    border-radius:5px;
}

.links{
    margin-top:10px;
}

.message{ color:green; }
.error{ color:red; }
</style>
</head>

<body>

<div class="container">
<h2>Forgot Password</h2>

{% if message %}<div class="message">{{ message }}</div>{% endif %}
{% if error %}<div class="error">{{ error }}</div>{% endif %}

<form method="POST">
<input type="email" name="email" placeholder="Enter your email" required>
<button type="submit">Reset Password</button>
</form>

<div class="links">
<a href="{{ url_for('login') }}">Back to Login</a>
</div>

</div>

</body>
</html>
"""

reset_page = """
<!DOCTYPE html>
<html>
<head>
<title>Reset Password</title>

<style>
body {
    font-family: Arial;
    background:#e6f0ff;
    display:flex;
    justify-content:center;
    align-items:center;
    height:100vh;
}

.container {
    background:#fff;
    padding:30px;
    border-radius:10px;
    width:350px;
    text-align:center;
    box-shadow:0 4px 10px rgba(0,0,0,0.2);
}

h2 {
    margin-bottom:15px;
}

.error {
    color:red;
    margin-bottom:10px;
}

/* INPUT */
input{
    width:100%;
    padding:10px;
    margin-top:8px;
    margin-bottom:10px;
    border-radius:5px;
    border:1px solid #ccc;
    box-sizing:border-box;
}

/* PASSWORD BOX */
.password-container{
    position:relative;
}

/* EYE ICON */
.toggle-password{
    position:absolute;
    right:10px;
    top:50%;
    transform:translateY(-50%);
    width:20px;
    cursor:pointer;
}

/* BUTTON */
button{
    width:100%;
    padding:10px;
    margin-top:20px;
    background:#0052cc;
    color:white;
    border:none;
    border-radius:5px;
}

button:disabled{
    background:#999;
}

/* CHECKLIST */
.checklist {
    font-size:12px;
    margin-top:10px;
    padding-left:0;
    text-align:left;
}

.checklist li {
    list-style:none;
    display:flex;
    align-items:center;
    gap:6px;
    margin-bottom:3px;
    color:#999;
}

.checklist li.valid {
    color:green;
}

.checklist li input{
    width:14px;
    height:14px;
    pointer-events:none;
}
</style>
</head>

<body>

<div class="container">

<h2>Reset Password</h2>

{% if error %}
<div class="error">{{ error }}</div>
{% endif %}

<form method="POST">

<!-- PASSWORD -->
<div class="password-container">
    <input type="password" id="password" name="password" placeholder="New Password (8+ characters)">
    <img src="{{ url_for('static', filename='close_eyes.jpg') }}"
         id="eye1"
         class="toggle-password"
         onclick="toggle('password','eye1')">
</div>

<!-- CONFIRM -->
<div class="password-container">
    <input type="password" id="confirm" name="confirm" placeholder="Confirm Password">
    <img src="{{ url_for('static', filename='close_eyes.jpg') }}"
         id="eye2"
         class="toggle-password"
         onclick="toggle('confirm','eye2')">
</div>

<!-- CHECKLIST -->
<ul class="checklist">
    <li id="u"><input type="checkbox" disabled> At least 1 uppercase</li>
    <li id="l"><input type="checkbox" disabled> At least 1 lowercase</li>
    <li id="n"><input type="checkbox" disabled> At least 1 number</li>
    <li id="s"><input type="checkbox" disabled> At least 1 special character</li>
</ul>

<button id="btn" type="submit" disabled>Update Password</button>

</form>

</div>

<script>

function toggle(id, eyeId){
    var input = document.getElementById(id);
    var eye = document.getElementById(eyeId);

    if(input.type === "password"){
        input.type = "text";
        eye.src = "{{ url_for('static', filename='open_eyes.jpg') }}";
    } else {
        input.type = "password";
        eye.src = "{{ url_for('static', filename='close_eyes.jpg') }}";
    }
}

var p = document.getElementById("password");
var c = document.getElementById("confirm");
var btn = document.getElementById("btn");

function check(){

    var val = p.value;
    var confirmVal = c.value;

    var up = /[A-Z]/.test(val);
    var lo = /[a-z]/.test(val);
    var nu = /[0-9]/.test(val);
    var sy = /[!@#$%^&*]/.test(val);
    var len = val.length >= 8;

    document.getElementById("u").className = up ? "valid" : "";
    document.getElementById("u").querySelector("input").checked = up;

    document.getElementById("l").className = lo ? "valid" : "";
    document.getElementById("l").querySelector("input").checked = lo;

    document.getElementById("n").className = nu ? "valid" : "";
    document.getElementById("n").querySelector("input").checked = nu;

    document.getElementById("s").className = sy ? "valid" : "";
    document.getElementById("s").querySelector("input").checked = sy;

    // ✅ NEW RULE:
    // button enable bila confirm ada isi (bukan match)
    var confirmFilled = confirmVal.length > 0;

    btn.disabled = !(confirmFilled && val.length > 0);
}

p.addEventListener("input", check);
c.addEventListener("input", check);

</script>

</body>
</html>
"""

# ================= ROUTES =================

@app.route("/", methods=["GET","POST"])
def login():
    error = None

    if request.method == "POST":
        u = request.form["username"]
        p = request.form["password"]

        user = User.query.filter_by(username=u).first()

        if user and check_password_hash(user.password, p):
            return redirect(url_for('home', username=u))
        else:
            error = "Wrong Username/Password"

    return render_template_string(login_page, error=error)


@app.route("/register", methods=["GET","POST"])
def register():
    error = None
    success = None

    # default values (IMPORTANT)
    fullname = ""
    username = ""
    email = ""
    password = ""
    confirm = ""

    if request.method == "POST":
        fullname = request.form["fullname"]
        username = request.form["username"]
        email = request.form["email"]
        password = request.form["password"]
        confirm = request.form["confirm_password"]

        # CHECK 1
        if User.query.filter_by(username=username).first():
            error = "Username exists"

        # CHECK 2
        elif len(password) < 8:
            error = "Password must be at least 8 characters"

        # CHECK 3
        elif password != confirm:
            error = "Password do not match"

        else:
            new_user = User(
                username=username,
                email=email,
                fullname=fullname,
                password=generate_password_hash(password)
            )
            db.session.add(new_user)
            db.session.commit()

            return redirect(url_for('login'))

    return render_template_string(
        register_page,
        error=error,
        success=success,
        fullname=fullname,
        username=username,
        email=email,
        password=password,
        confirm_password=confirm
    )

@app.route("/home/<username>")
def home(username):

    user = User.query.filter_by(username=username).first()

    if not user:
        return redirect(url_for("login"))

    return render_template_string(
        home_page,
        username=user.username,
        fullname=user.fullname,
        user=user
    )

@app.route("/profile/<username>", methods=["GET","POST"])
def profile(username):

    user = User.query.filter_by(username=username).first()

    if not user:
        return redirect(url_for("login"))

    if request.method == "POST":

        # ========= UPLOAD GAMBAR =========
        file = request.files.get("profile_pic")

        if file and file.filename != "":
            filename = secure_filename(file.filename)
            filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename)
            file.save(filepath)

            if hasattr(user, 'profile_pic'):
                user.profile_pic = filename

        # ========= UPDATE PROFILE =========
        new_username = request.form.get("username")
        new_email = request.form.get("email")
        new_phone = request.form.get("phone")
        new_fullname = request.form.get("fullname")

        if new_username:
            user.username = new_username
        if new_email:
            user.email = new_email
        if new_phone:
            user.phone = new_phone
        if new_fullname:
            user.fullname = new_fullname

        db.session.commit()

        return redirect(url_for("profile", username=user.username))

    return render_template_string(
        profile_page,
        username=user.username,
        email=user.email,
        phone=user.phone,
        fullname=user.fullname,
        user=user
    )

import uuid

@app.route("/forgot-password", methods=["GET","POST"])
def forgot_password():
    message = None
    error = None

    if request.method == "POST":
        email = request.form["email"]

        user = User.query.filter_by(email=email).first()

        if user:
            token = str(uuid.uuid4())   # generate token
            user.reset_token = token
            db.session.commit()

            reset_link = url_for('reset_password', token=token, _external=True)

            print("RESET LINK:", reset_link)  # simulate email

            message = "Kindly check your email for reset password"
        else:
            error = "Email not found"

    return render_template_string(forgot_page, message=message, error=error)

@app.route("/reset-password/<token>", methods=["GET","POST"])
def reset_password(token):

    user = User.query.filter_by(reset_token=token).first()

    if not user:
        return "Invalid or expired token"

    error = None

    if request.method == "POST":
        new_password = request.form["password"]
        confirm = request.form["confirm"]

        if new_password != confirm:
            error = "Password not match"
        elif len(new_password) < 8:
            error = "Password must be at least 8 characters"
        else:
            user.password = generate_password_hash(new_password)
            user.reset_token = None
            db.session.commit()

            return redirect(url_for("login"))

    return render_template_string(reset_page, error=error)

@app.route("/remove-profile-pic", methods=["POST"])
def remove_profile_pic():
    username = request.args.get("username")
    user = User.query.filter_by(username=username).first()

    if user:
        user.profile_pic = None
        db.session.commit()

    return "ok"

if __name__ == "__main__":
    app.run()