#!/usr/bin/env python3
# build_chatapp_pro_files.py
# نسخه حرفه‌ای پیام‌رسان با PHP + MySQL + WebSocket + ارسال فایل و عکس
# مسیر پیشفرض: /var/www/html/chatapp/

import os

BASE_DIR = "/var/www/html/chatapp"

folders = [
    "config",
    "public",
    "public/js",
    "public/css",
    "public/uploads",
    "server",
    "includes",
    "sql"
]

for folder in folders:
    path = os.path.join(BASE_DIR, folder)
    os.makedirs(path, exist_ok=True)

# -----------------------------
# config/config.php
config_php = """<?php
$DB_HOST = 'localhost';
$DB_NAME = 'chatapp';
$DB_USER = 'root';
$DB_PASS = '';
try {
    $pdo = new PDO("mysql:host=$DB_HOST;dbname=$DB_NAME;charset=utf8", $DB_USER, $DB_PASS);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
    die("Connection failed: " . $e->getMessage());
}
?>
"""
with open(os.path.join(BASE_DIR, "config/config.php"), "w") as f:
    f.write(config_php)

# -----------------------------
# includes/db.php
db_php = """<?php
require_once __DIR__ . '/../config/config.php';
?>
"""
with open(os.path.join(BASE_DIR, "includes/db.php"), "w") as f:
    f.write(db_php)

# -----------------------------
# includes/auth.php
auth_php = """<?php
session_start();
require_once 'db.php';

function login($username, $password){
    global $pdo;
    $stmt = $pdo->prepare("SELECT * FROM users WHERE username=?");
    $stmt->execute([$username]);
    $user = $stmt->fetch(PDO::FETCH_ASSOC);
    if($user && password_verify($password, $user['password'])){
        $_SESSION['user_id'] = $user['id'];
        $_SESSION['username'] = $user['username'];
        return true;
    }
    return false;
}

function register($username, $password){
    global $pdo;
    $hash = password_hash($password, PASSWORD_DEFAULT);
    $stmt = $pdo->prepare("INSERT INTO users (username, password) VALUES (?, ?)");
    return $stmt->execute([$username, $hash]);
}

function isLoggedIn(){ return isset($_SESSION['user_id']); }

function currentUserId(){ return $_SESSION['user_id'] ?? 0; }
?>
"""
with open(os.path.join(BASE_DIR, "includes/auth.php"), "w") as f:
    f.write(auth_php)

# -----------------------------
# sql/schema.sql
schema_sql = """CREATE DATABASE IF NOT EXISTS chatapp;
USE chatapp;

CREATE TABLE IF NOT EXISTS users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(50) UNIQUE NOT NULL,
    password VARCHAR(255) NOT NULL,
    status ENUM('offline','online') DEFAULT 'offline',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE IF NOT EXISTS messages (
    id INT AUTO_INCREMENT PRIMARY KEY,
    sender_id INT NOT NULL,
    receiver_id INT DEFAULT NULL,
    group_id INT DEFAULT NULL,
    message TEXT DEFAULT NULL,
    file_path VARCHAR(255) DEFAULT NULL,
    file_type VARCHAR(50) DEFAULT NULL,
    is_read TINYINT(1) DEFAULT 0,
    sent_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (sender_id) REFERENCES users(id)
);

CREATE TABLE IF NOT EXISTS groups (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE IF NOT EXISTS group_members (
    id INT AUTO_INCREMENT PRIMARY KEY,
    group_id INT NOT NULL,
    user_id INT NOT NULL,
    FOREIGN KEY (group_id) REFERENCES groups(id),
    FOREIGN KEY (user_id) REFERENCES users(id)
);
"""
with open(os.path.join(BASE_DIR, "sql/schema.sql"), "w") as f:
    f.write(schema_sql)

# -----------------------------
# public/index.php
index_php = """<?php
require_once '../includes/auth.php';
$message = '';
if($_SERVER['REQUEST_METHOD']=='POST'){
    if(isset($_POST['login'])){
        if(login($_POST['username'], $_POST['password'])){
            header('Location: chat.php'); exit;
        } else { $message='نام کاربری یا رمز عبور اشتباه است'; }
    } elseif(isset($_POST['register'])){
        if(register($_POST['username'], $_POST['password'])){
            $message='ثبت‌نام موفق! حالا وارد شوید.';
        } else { $message='خطا در ثبت‌نام یا نام کاربری موجود است'; }
    }
}
?>
<!DOCTYPE html>
<html lang="fa">
<head>
<meta charset="UTF-8">
<title>پیام‌رسان حرفه‌ای</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div class="login-box">
<h2>ورود / ثبت‌نام</h2>
<form method="POST" enctype="multipart/form-data">
<input type="text" name="username" placeholder="نام کاربری" required><br>
<input type="password" name="password" placeholder="رمز عبور" required><br>
<button name="login">ورود</button>
<button name="register">ثبت‌نام</button>
</form>
<p><?php echo $message; ?></p>
</div>
</body>
</html>
"""
with open(os.path.join(BASE_DIR, "public/index.php"), "w") as f:
    f.write(index_php)

# -----------------------------
# public/chat.php
chat_php = """<?php
require_once '../includes/auth.php';
if(!isLoggedIn()){ header('Location: index.php'); exit; }
?>
<!DOCTYPE html>
<html lang="fa">
<head>
<meta charset="UTF-8">
<title>چت حرفه‌ای</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div class="chat-container">
<div class="sidebar" id="userList"></div>
<div class="chat-window" id="chatWindow"></div>
<input type="text" id="msgInput" placeholder="پیام خود را بنویسید">
<input type="file" id="fileInput">
<button id="sendBtn">ارسال</button>
</div>
<script>
const currentUser = '<?php echo $_SESSION["username"]; ?>';
</script>
<script src="js/chat_pro.js"></script>
</body>
</html>
"""
with open(os.path.join(BASE_DIR, "public/chat.php"), "w") as f:
    f.write(chat_php)

# -----------------------------
# public/css/style.css
style_css = """body{font-family:sans-serif;background:#f0f0f0;}
.login-box{width:300px;margin:100px auto;padding:20px;background:#fff;border-radius:10px;text-align:center;}
.chat-container{display:flex;width:700px;margin:50px auto;background:#fff;padding:10px;border-radius:10px;}
.sidebar{width:200px;border-right:1px solid #ccc;padding:5px;overflow-y:auto;height:400px;}
.chat-window{flex:1;height:400px;overflow-y:scroll;border:1px solid #ccc;padding:10px;margin-left:10px;}
#msgInput{width:60%;padding:5px;} #fileInput{width:20%;} #sendBtn{padding:5px;}
"""
with open(os.path.join(BASE_DIR, "public/css/style.css"), "w") as f:
    f.write(style_css)

# -----------------------------
# public/js/chat_pro.js
chat_js = """let ws = new WebSocket('ws://127.0.0.1:8080/chat');
let chatWindow = document.getElementById('chatWindow');
let userList = document.getElementById('userList');
let sendBtn = document.getElementById('sendBtn');
let msgInput = document.getElementById('msgInput');
let fileInput = document.getElementById('fileInput');

ws.onopen = ()=>{ console.log('WebSocket connected'); };
ws.onmessage = function(event){
    let data = JSON.parse(event.data);
    if(data.type=='message'){
        let msgHtml = '<b>'+data.sender+':</b> '+(data.message||'');
        if(data.file_path){
            if(data.file_type.startsWith('image')){
                msgHtml += '<br><img src="'+data.file_path+'" width="150">';
            } else {
                msgHtml += '<br><a href="'+data.file_path+'" target="_blank">دانلود فایل</a>';
            }
        }
        chatWindow.innerHTML += '<p>'+msgHtml+'</p>';
        chatWindow.scrollTop = chatWindow.scrollHeight;
    } else if(data.type=='users'){
        userList.innerHTML = '';
        data.users.forEach(u=>{
            let el = document.createElement('div'); el.textContent = u;
            userList.appendChild(el);
        });
    }
};

sendBtn.onclick = function(){
    let msg = msgInput.value.trim();
    let file = fileInput.files[0];
    if(msg=='' && !file) return;

    let formData = new FormData();
    formData.append('message', msg);
    formData.append('sender', currentUser);
    if(file) formData.append('file', file);

    fetch('send_message.php', { method:'POST', body: formData });
    msgInput.value = '';
    fileInput.value = '';
};
"""
with open(os.path.join(BASE_DIR, "public/js/chat_pro.js"), "w") as f:
    f.write(chat_js)

# -----------------------------
# public/send_message.php
send_message_php = """<?php
require_once '../includes/auth.php';
require_once '../includes/db.php';

$sender = currentUserId();
$receiver = null;
$message = $_POST['message'] ?? '';
$file_path = null;
$file_type = null;

if(isset($_FILES['file']) && $_FILES['file']['error'] == 0){
    $targetDir = '../uploads/';
    if(!is_dir($targetDir)) mkdir($targetDir, 0777, true);

    $filename = time() . '_' . basename($_FILES['file']['name']);
    $targetFile = $targetDir . $filename;
    if(move_uploaded_file($_FILES['file']['tmp_name'], $targetFile)){
        $file_path = 'uploads/' . $filename;
        $file_type = mime_content_type($targetFile);
    }
}

$stmt = $pdo->prepare("INSERT INTO messages (sender_id, receiver_id, message, file_path, file_type) VALUES (?,?,?,?,?)");
$stmt->execute([$sender, $receiver, $message, $file_path, $file_type]);
?>
"""
with open(os.path.join(BASE_DIR, "public/send_message.php"), "w") as f:
    f.write(send_message_php)

# -----------------------------
# server/WebSocketServer.php
websocket_php = """<?php
require __DIR__ . '/../vendor/autoload.php';
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;

class ChatServer implements MessageComponentInterface {
    protected $clients;
    public function __construct(){ $this->clients = new \SplObjectStorage; }
    public function onOpen(ConnectionInterface $conn){ $this->clients->attach($conn); }
    public function onMessage(ConnectionInterface $from, $msg){
        foreach($this->clients as $client){ $client->send($msg); }
    }
    public function onClose(ConnectionInterface $conn){ $this->clients->detach($conn); }
    public function onError(ConnectionInterface $conn, \Exception $e){ $conn->close(); }
}

$server = \Ratchet\Server\IoServer::factory(
    new \Ratchet\Http\HttpServer(
        new \Ratchet\WebSocket\WsServer(
            new ChatServer()
        )
    ), 8080
);
$server->run();
?>
"""
with open(os.path.join(BASE_DIR, "server/WebSocketServer.php"), "w") as f:
    f.write(websocket_php)

print("نسخه حرفه‌ای پیام‌رسان با ارسال فایل ساخته شد ✅")
print("مسیر پروژه:", BASE_DIR)
print("دیتابیس: sql/schema.sql")
print("پوشه آپلود فایل‌ها: public/uploads")
print("برای نصب WebSocket: composer require cboden/ratchet")
print("برای اجرا: php server/WebSocketServer.php")
