import logging
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import os
import json
import sqlite3
import uuid
import hashlib
import datetime
import traceback
import mimetypes
import requests
from flask import Flask, request, jsonify, send_from_directory
from flask_cors import CORS
from werkzeug.utils import secure_filename

app = Flask(__name__)
app.config['SECRET_KEY'] = 'your-secret-key-change-this'
app.config['UPLOAD_FOLDER'] = '/opt/sitechat/uploads'
app.config['MAX_CONTENT_LENGTH'] = 50 * 1024 * 1024

CORS(app, origins='*', methods=['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
     allow_headers=['Content-Type', 'Authorization'])

DB_PATH = '/opt/sitechat/database/sqlite.db'
UPLOAD_FOLDER = '/opt/sitechat/uploads'

os.makedirs(UPLOAD_FOLDER, exist_ok=True)
os.makedirs(os.path.dirname(DB_PATH), exist_ok=True)

def get_db():

def get_admin_settings(admin_id="admin"):
    try:
        conn = get_db()
        cursor = conn.cursor()
        cursor.execute("SELECT * FROM admin_settings WHERE admin_id = ?", (admin_id,))
        result = cursor.fetchone()
        conn.close()
        return dict(result) if result else None
    except:
        return None

def update_admin_settings(admin_id, data):
    try:
        conn = get_db()
        cursor = conn.cursor()
        email = data.get("email", "").strip()
        notifications_enabled = 1 if data.get("notifications_enabled", 1) else 0
        cursor.execute("SELECT id FROM admin_settings WHERE admin_id = ?", (admin_id,))
        existing = cursor.fetchone()
        if existing:
            if "password" in data and data["password"]:
                password_hash = hashlib.sha256(data["password"].encode()).hexdigest()
                cursor.execute("UPDATE admin_settings SET email = ?, password_hash = ?, notifications_enabled = ?, updated_at = CURRENT_TIMESTAMP WHERE admin_id = ?", (email, password_hash, notifications_enabled, admin_id))
            else:
                cursor.execute("UPDATE admin_settings SET email = ?, notifications_enabled = ?, updated_at = CURRENT_TIMESTAMP WHERE admin_id = ?", (email, notifications_enabled, admin_id))
        else:
            password_hash = hashlib.sha256(data.get("password", "").encode()).hexdigest() if "password" in data and data["password"] else ""
            cursor.execute("INSERT INTO admin_settings (admin_id, email, password_hash, notifications_enabled) VALUES (?, ?, ?, ?)", (admin_id, email, password_hash, notifications_enabled))
        conn.commit()
        conn.close()
        return True
    except Exception as e:
        print(f"Error updating admin settings: {e}")
        return False

def get_smtp_settings():
    try:
        conn = get_db()
        cursor = conn.cursor()
        cursor.execute("SELECT * FROM smtp_settings ORDER BY id DESC LIMIT 1")
        result = cursor.fetchone()
        conn.close()
        return dict(result) if result else None
    except:
        return None

def update_smtp_settings(data):
    try:
        conn = get_db()
        cursor = conn.cursor()
        server = data.get("server", "").strip()
        port = int(data.get("port", 25))
        username = data.get("username", "").strip()
        password = data.get("password", "").strip()
        from_email = data.get("from_email", "").strip()
        use_tls = int(data.get("use_tls", 0))
        use_ssl = int(data.get("use_ssl", 0))
        cursor.execute("SELECT id FROM smtp_settings LIMIT 1")
        existing = cursor.fetchone()
        if existing:
            cursor.execute("UPDATE smtp_settings SET server = ?, port = ?, username = ?, password = ?, from_email = ?, use_tls = ?, use_ssl = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?", (server, port, username, password, from_email, use_tls, use_ssl, existing[0]))
        else:
            cursor.execute("INSERT INTO smtp_settings (server, port, username, password, from_email, use_tls, use_ssl) VALUES (?, ?, ?, ?, ?, ?, ?)", (server, port, username, password, from_email, use_tls, use_ssl))
        conn.commit()
        conn.close()
        return True
    except Exception as e:
        print(f"Error updating SMTP settings: {e}")
        return False

def send_email_notification(to_email, subject, body):
    try:
        settings = get_smtp_settings()
        if not settings:
            return False, "SMTP настройки не найдены"
        server = settings.get("server", "")
        port = int(settings.get("port", 25))
        username = settings.get("username", "")
        password = settings.get("password", "")
        from_email = settings.get("from_email", "") or username
        use_tls = int(settings.get("use_tls", 0))
        use_ssl = int(settings.get("use_ssl", 0))
        if not server or not username or not password:
            return False, "Не заполнены SMTP настройки"
        import smtplib, ssl
        from email.mime.text import MIMEText
        from email.mime.multipart import MIMEMultipart
        if use_ssl:
            context = ssl.create_default_context()
            smtp = smtplib.SMTP_SSL(server, port, context=context, timeout=30)
        else:
            smtp = smtplib.SMTP(server, port, timeout=30)
        smtp.ehlo()
        if use_tls and not use_ssl:
            smtp.starttls()
            smtp.ehlo()
        smtp.login(username, password)
        msg = MIMEMultipart()
        msg["From"] = from_email
        msg["To"] = to_email
        msg["Subject"] = subject
        msg.attach(MIMEText(body, "plain", "utf-8"))
        smtp.sendmail(from_email, to_email, msg.as_string())
        smtp.quit()
        return True, "Письмо отправлено"
    except Exception as e:
        return False, str(e)
    conn = sqlite3.connect(DB_PATH)
    conn.row_factory = sqlite3.Row
    return conn

def get_client_ip():
    if request.headers.get('X-Forwarded-For'):
        ip = request.headers.get('X-Forwarded-For').split(',')[0].strip()
    elif request.headers.get('X-Real-IP'):
        ip = request.headers.get('X-Real-IP')
    else:
        ip = request.remote_addr
    return ip

def get_geo_info(ip):
    if ip == '127.0.0.1' or ip.startswith('192.168.') or ip.startswith('10.') or ip.startswith('172.'):
        return {'city': 'Локальная сеть', 'country': 'LAN', 'region': '', 'full': 'Локальная сеть'}
    try:
        response = requests.get(f'http://ip-api.com/json/{ip}', timeout=3)
        if response.status_code == 200:
            data = response.json()
            if data.get('status') == 'success':
                city = data.get('city', '')
                country = data.get('country', '')
                region = data.get('regionName', '')
                return {'city': city, 'country': country, 'region': region, 'full': f"{city}, {country}" if city else country}
    except Exception as e:
        print(f"Geo error: {e}")
    return {'city': '', 'country': '', 'region': '', 'full': 'Неизвестно'}

@app.route('/', methods=['GET', 'OPTIONS'])
def index():
    if request.method == 'OPTIONS':
        return '', 200
    return jsonify({'status': 'ok', 'message': 'Chat server is running'})

@app.route('/admin', methods=['GET', 'OPTIONS'])
def admin():
    if request.method == 'OPTIONS':
        return '', 200
    try:
        with open('/opt/sitechat/templates/admin.html', 'r', encoding='utf-8') as f:
            return f.read()
    except Exception as e:
        return jsonify({'error': str(e)}), 404

@app.route('/api/check_db', methods=['GET', 'OPTIONS'])
def check_db():
    if request.method == 'OPTIONS':
        return '', 200
    return jsonify({'exists': os.path.exists(DB_PATH), 'integrity': True})

# ============================================================
# НАСТРОЙКИ ПРОФИЛЯ И SMTP
# ============================================================

@app.route("/api/admin/profile", methods=["GET", "OPTIONS"])
def get_profile():
    if request.method == "OPTIONS": return "", 200
    try:
        settings = get_admin_settings("admin")
        if settings:
            settings.pop("password_hash", None)
            settings.pop("id", None)
            return jsonify(settings)
        return jsonify({"error": "Настройки не найдены"}), 404
    except Exception as e:
        return jsonify({"error": str(e)}), 500

@app.route("/api/admin/profile", methods=["POST", "OPTIONS"])
def update_profile():
    if request.method == "OPTIONS": return "", 200
    try:
        data = request.json
        if "new_password" in data and data["new_password"]:
            if "current_password" not in data:
                return jsonify({"error": "Текущий пароль обязателен"}), 400
            conn = get_db()
            cursor = conn.cursor()
            cursor.execute("SELECT password_hash FROM admins WHERE username = "admin"")
            row = cursor.fetchone()
            conn.close()
            if row and row[0] != hashlib.sha256(data["current_password"].encode()).hexdigest():
                return jsonify({"error": "Неверный текущий пароль"}), 401
            update_data = {"email": data.get("email", ""), "password": data["new_password"], "notifications_enabled": data.get("notifications_enabled", 1)}
        else:
            update_data = {"email": data.get("email", ""), "notifications_enabled": data.get("notifications_enabled", 1)}
        if update_admin_settings("admin", update_data):
            return jsonify({"success": True, "message": "Профиль обновлен"})
        return jsonify({"error": "Ошибка сохранения"}), 500
    except Exception as e:
        return jsonify({"error": str(e)}), 500

@app.route("/api/admin/smtp", methods=["GET", "OPTIONS"])
def get_smtp():
    if request.method == "OPTIONS": return "", 200
    try:
        settings = get_smtp_settings()
        if settings:
            if settings.get("password"):
                settings["password"] = "***"
            settings.pop("id", None)
            return jsonify(settings)
        return jsonify({"error": "SMTP настройки не найдены"}), 404
    except Exception as e:
        return jsonify({"error": str(e)}), 500

@app.route("/api/admin/smtp", methods=["POST", "OPTIONS"])
def update_smtp():
    if request.method == "OPTIONS": return "", 200
    try:
        data = request.json
        if data.get("password") == "***":
            old = get_smtp_settings()
            if old: data["password"] = old.get("password", "")
        if update_smtp_settings(data):
            return jsonify({"success": True, "message": "SMTP настройки сохранены"})
        return jsonify({"error": "Ошибка сохранения"}), 500
    except Exception as e:
        return jsonify({"error": str(e)}), 500

@app.route("/api/admin/smtp/test", methods=["POST", "OPTIONS"])
def test_smtp():
    if request.method == "OPTIONS": return "", 200
    try:
        data = request.json
        if data.get("password") == "***":
            old = get_smtp_settings()
            if old: data["password"] = old.get("password", "")
        to_email = data.get("test_email")
        if not to_email:
            settings = get_admin_settings("admin")
            to_email = settings.get("email") if settings else None
        if not to_email:
            return jsonify({"success": False, "error": "Email получателя не указан"})
        subject = "Тестовое письмо от чата"
        body = f"Это тестовое письмо для проверки SMTP настроек.\n\nДата: {__import__(datetime).datetime.now().strftime(%Y-%m-%d
@app.route('/api/admin/login', methods=['POST', 'OPTIONS'])
def admin_login():
    if request.method == 'OPTIONS':
        return '', 200
    data = request.json
    if data.get('username') == 'admin' and data.get('password') == 'admin123':
        token = str(uuid.uuid4()) + str(uuid.uuid4()).replace('-', '')
        return jsonify({'token': token})
    return jsonify({'error': 'Invalid credentials'}), 401

@app.route('/api/admin/users', methods=['GET', 'OPTIONS'])
def get_users():
    if request.method == 'OPTIONS':
        return '', 200
    conn = get_db()
    users = conn.execute('SELECT user_id, created_at, last_seen, last_ip, last_location, city, country FROM users ORDER BY created_at DESC').fetchall()
    result = []
    for user in users:
        user_dict = dict(user)
        last = conn.execute('SELECT text, timestamp, sender FROM messages WHERE user_id = ? ORDER BY timestamp DESC LIMIT 1', (user_dict['user_id'],)).fetchone()
        if last:
            user_dict['last_message'] = last['text'][:50] if last['text'] else '[Файл]'
            user_dict['last_message_time'] = last['timestamp']
        else:
            user_dict['last_message'] = ''
            user_dict['last_message_time'] = ''
        user_dict['has_unread'] = conn.execute('SELECT COUNT(*) FROM messages WHERE user_id = ? AND sender="user" AND is_read=0', (user_dict['user_id'],)).fetchone()[0] > 0
        result.append(user_dict)
    conn.close()
    return jsonify(result)

@app.route('/api/admin/users_paginated', methods=['POST', 'OPTIONS'])
def get_users_paginated():
    if request.method == 'OPTIONS':
        return '', 200
    data = request.json
    page = data.get('page', 1)
    limit = data.get('limit', 25)
    offset = (page - 1) * limit
    
    conn = get_db()
    cursor = conn.cursor()
    
    cursor.execute('SELECT COUNT(*) as total FROM users')
    total = cursor.fetchone()['total']
    
    cursor.execute('''
        SELECT user_id, created_at, last_seen, last_ip, last_location, city, country 
        FROM users ORDER BY created_at DESC LIMIT ? OFFSET ?
    ''', (limit, offset))
    users = cursor.fetchall()
    
    result = []
    for user in users:
        user_dict = dict(user)
        last = cursor.execute('SELECT text, timestamp, sender FROM messages WHERE user_id = ? ORDER BY timestamp DESC LIMIT 1', (user_dict['user_id'],)).fetchone()
        if last:
            user_dict['last_message'] = last['text'][:50] if last['text'] else '[Файл]'
            user_dict['last_message_time'] = last['timestamp']
        else:
            user_dict['last_message'] = ''
            user_dict['last_message_time'] = ''
        user_dict['has_unread'] = cursor.execute('SELECT COUNT(*) FROM messages WHERE user_id = ? AND sender="user" AND is_read=0', (user_dict['user_id'],)).fetchone()[0] > 0
        result.append(user_dict)
    
    conn.close()
    
    return jsonify({
        'users': result,
        'total': total,
        'page': page,
        'limit': limit,
        'total_pages': (total + limit - 1) // limit if limit > 0 else 1
    })

@app.route('/api/admin/users_with_unread', methods=['GET', 'OPTIONS'])
def get_users_with_unread():
    if request.method == 'OPTIONS':
        return '', 200
    conn = get_db()
    
    users = conn.execute('''
        SELECT DISTINCT u.user_id, u.created_at, u.last_seen, u.last_ip, u.last_location, u.city, u.country
        FROM users u
        INNER JOIN messages m ON u.user_id = m.user_id
        WHERE m.sender = 'user' AND m.is_read = 0
        ORDER BY m.timestamp DESC
    ''').fetchall()
    
    result = []
    for user in users:
        user_dict = dict(user)
        last = conn.execute('SELECT text, timestamp, sender FROM messages WHERE user_id = ? ORDER BY timestamp DESC LIMIT 1', (user_dict['user_id'],)).fetchone()
        if last:
            user_dict['last_message'] = last['text'][:50] if last['text'] else '[Файл]'
            user_dict['last_message_time'] = last['timestamp']
        else:
            user_dict['last_message'] = ''
            user_dict['last_message_time'] = ''
        user_dict['has_unread'] = True
        result.append(user_dict)
    
    conn.close()
    return jsonify(result)

@app.route('/api/admin/users_with_messages', methods=['GET', 'OPTIONS'])
def get_users_with_messages():
    """Получение всех пользователей с реальными сообщениями (не системными)"""
    if request.method == 'OPTIONS':
        return '', 200
    conn = get_db()
    cursor = conn.cursor()
    
    cursor.execute('''
        SELECT DISTINCT u.user_id, u.created_at, u.last_seen, u.last_ip, u.last_location, u.city, u.country
        FROM users u
        INNER JOIN messages m ON u.user_id = m.user_id
        WHERE m.sender = 'user' OR m.sender = 'admin'
        ORDER BY u.created_at DESC
    ''')
    users = cursor.fetchall()
    
    result = []
    for user in users:
        user_dict = dict(user)
        last = cursor.execute('SELECT text, timestamp, sender FROM messages WHERE user_id = ? AND (sender = "user" OR sender = "admin") ORDER BY timestamp DESC LIMIT 1', (user_dict['user_id'],)).fetchone()
        if last:
            user_dict['last_message'] = last['text'][:50] if last['text'] else '[Файл]'
            user_dict['last_message_time'] = last['timestamp']
        else:
            user_dict['last_message'] = ''
            user_dict['last_message_time'] = ''
        user_dict['has_unread'] = cursor.execute('SELECT COUNT(*) FROM messages WHERE user_id = ? AND sender="user" AND is_read=0', (user_dict['user_id'],)).fetchone()[0] > 0
        result.append(user_dict)
    
    conn.close()
    return jsonify(result)

@app.route('/api/admin/new_users', methods=['GET', 'OPTIONS'])
def get_new_users():
    """Получение новых пользователей (с момента последнего запроса)"""
    if request.method == 'OPTIONS':
        return '', 200
    
    last_check = request.args.get('last_check', '')
    
    conn = get_db()
    cursor = conn.cursor()
    
    if last_check:
        cursor.execute('''
            SELECT DISTINCT u.user_id, u.created_at, u.last_seen, u.last_ip, u.last_location, u.city, u.country
            FROM users u
            INNER JOIN messages m ON u.user_id = m.user_id
            WHERE m.timestamp > ?
            ORDER BY m.timestamp DESC
        ''', (last_check,))
    else:
        cursor.execute('''
            SELECT DISTINCT u.user_id, u.created_at, u.last_seen, u.last_ip, u.last_location, u.city, u.country
            FROM users u
            INNER JOIN messages m ON u.user_id = m.user_id
            ORDER BY m.timestamp DESC
            LIMIT 50
        ''')
    
    users = cursor.fetchall()
    
    result = []
    for user in users:
        user_dict = dict(user)
        last = cursor.execute('SELECT text, timestamp, sender FROM messages WHERE user_id = ? ORDER BY timestamp DESC LIMIT 1', (user_dict['user_id'],)).fetchone()
        if last:
            user_dict['last_message'] = last['text'][:50] if last['text'] else '[Файл]'
            user_dict['last_message_time'] = last['timestamp']
        else:
            user_dict['last_message'] = ''
            user_dict['last_message_time'] = ''
        user_dict['has_unread'] = cursor.execute('SELECT COUNT(*) FROM messages WHERE user_id = ? AND sender="user" AND is_read=0', (user_dict['user_id'],)).fetchone()[0] > 0
        result.append(user_dict)
    
    conn.close()
    return jsonify(result)

@app.route('/api/admin/search', methods=['POST', 'OPTIONS'])
def search_users():
    if request.method == 'OPTIONS':
        return '', 200
    data = request.json
    query = data.get('query', '').strip()
    
    if not query:
        return jsonify({'users': []})
    
    conn = get_db()
    cursor = conn.cursor()
    
    cursor.execute('SELECT user_id FROM users WHERE user_id LIKE ?', (f'%{query}%',))
    users_by_id = [row['user_id'] for row in cursor.fetchall()]
    
    cursor.execute('''
        SELECT DISTINCT user_id FROM messages 
        WHERE text LIKE ? AND sender != 'system'
        ORDER BY timestamp DESC
    ''', (f'%{query}%',))
    users_by_message = [row['user_id'] for row in cursor.fetchall()]
    
    all_user_ids = list(set(users_by_id + users_by_message))
    
    result = []
    for user_id in all_user_ids:
        cursor.execute('SELECT user_id, created_at, last_seen, last_ip, last_location, city, country FROM users WHERE user_id = ?', (user_id,))
        user = cursor.fetchone()
        if user:
            user_dict = dict(user)
            last = cursor.execute('SELECT text, timestamp, sender FROM messages WHERE user_id = ? ORDER BY timestamp DESC LIMIT 1', (user_id,)).fetchone()
            if last:
                user_dict['last_message'] = last['text'][:50] if last['text'] else '[Файл]'
                user_dict['last_message_time'] = last['timestamp']
            else:
                user_dict['last_message'] = ''
                user_dict['last_message_time'] = ''
            user_dict['has_unread'] = cursor.execute('SELECT COUNT(*) FROM messages WHERE user_id = ? AND sender="user" AND is_read=0', (user_id,)).fetchone()[0] > 0
            result.append(user_dict)
    
    conn.close()
    return jsonify({'users': result, 'query': query})

@app.route('/api/admin/messages/<user_id>', methods=['GET', 'OPTIONS'])
def get_user_messages(user_id):
    if request.method == 'OPTIONS':
        return '', 200
    conn = get_db()
    messages = conn.execute('SELECT message_id as id, sender, text, file_info as file, timestamp FROM messages WHERE user_id = ? ORDER BY timestamp ASC', (user_id,)).fetchall()
    result = []
    for msg in messages:
        msg_dict = dict(msg)
        if msg_dict.get('file'):
            try:
                msg_dict['file'] = json.loads(msg_dict['file'])
            except:
                pass
        result.append(msg_dict)
    conn.close()
    return jsonify(result)

@app.route('/api/admin/send', methods=['POST', 'OPTIONS'])
def admin_send_message():
    if request.method == 'OPTIONS':
        return '', 200
    data = request.json
    user_id = data.get('user_id')
    text = data.get('message')
    msg_id = str(uuid.uuid4())
    timestamp = datetime.datetime.now().isoformat()
    conn = get_db()
    conn.execute('INSERT INTO messages (user_id, message_id, sender, text, timestamp, is_read) VALUES (?, ?, ?, ?, ?, ?)',
                 (user_id, msg_id, 'admin', text, timestamp, 1))
    conn.commit()
    conn.close()
    return jsonify({'success': True, 'id': msg_id, 'timestamp': timestamp})

@app.route('/api/admin/mark_read/<user_id>', methods=['POST', 'OPTIONS'])
def mark_user_read(user_id):
    if request.method == 'OPTIONS':
        return '', 200
    conn = get_db()
    conn.execute('UPDATE messages SET is_read = 1 WHERE user_id = ? AND sender = "user"', (user_id,))
    conn.commit()
    conn.close()
    return jsonify({'success': True})

@app.route('/api/admin/edit_message', methods=['PUT', 'OPTIONS'])
def admin_edit_message():
    if request.method == 'OPTIONS':
        return '', 200
    data = request.json
    user_id = data.get('user_id')
    message_id = data.get('message_id')
    new_text = data.get('new_text')
    conn = get_db()
    conn.execute('UPDATE messages SET text = ?, is_edited = 1, edited_at = ? WHERE user_id = ? AND message_id = ?',
                 (new_text, datetime.datetime.now().isoformat(), user_id, message_id))
    conn.commit()
    conn.close()
    return jsonify({'success': True})

@app.route('/api/admin/delete_message', methods=['DELETE', 'OPTIONS'])
def admin_delete_message():
    if request.method == 'OPTIONS':
        return '', 200
    data = request.json
    user_id = data.get('user_id')
    message_id = data.get('message_id')
    conn = get_db()
    conn.execute('DELETE FROM messages WHERE user_id = ? AND message_id = ?', (user_id, message_id))
    conn.commit()
    conn.close()
    return jsonify({'success': True})

@app.route('/api/register', methods=['POST', 'OPTIONS'])
def register_user():
    if request.method == 'OPTIONS':
        return '', 200
    user_id = str(uuid.uuid4())[:8]
    client_ip = get_client_ip()
    geo_info = get_geo_info(client_ip)
    timestamp = datetime.datetime.now().isoformat()
    conn = get_db()
    conn.execute('INSERT INTO users (user_id, created_at, last_seen, last_ip, last_location, city, country, region) VALUES (?, ?, ?, ?, ?, ?, ?, ?)',
                 (user_id, timestamp, timestamp, client_ip, geo_info.get('full', ''), geo_info.get('city', ''), geo_info.get('country', ''), geo_info.get('region', '')))
    conn.commit()
    conn.close()
    
    welcome_msg_id = str(uuid.uuid4())
    welcome_text = 'Для возможности просмотра истории сообщений <a href="#" onclick="showPasswordForm(); return false;" style="color: #25D366; text-decoration: underline; cursor: pointer;">задайте пароль</a>.\n\nЗапомните свой ID для последующего использования в чате.\nДля восстановления истории сообщений измените ID в заголовке окна и введите пароль.'
    
    conn = get_db()
    conn.execute('INSERT INTO messages (user_id, message_id, sender, text, timestamp, is_read) VALUES (?, ?, ?, ?, ?, ?)',
                 (user_id, welcome_msg_id, 'system', welcome_text, timestamp, 1))
    conn.commit()
    conn.close()
    return jsonify({'user_id': user_id, 'profile': {'user_id': user_id}, 'history': []})

@app.route('/api/login', methods=['POST', 'OPTIONS'])
def user_login():
    if request.method == 'OPTIONS':
        return '', 200
    data = request.json
    user_id = data.get('user_id')
    password = data.get('password', '')
    
    conn = get_db()
    user = conn.execute('SELECT * FROM users WHERE user_id = ?', (user_id,)).fetchone()
    if not user:
        conn.close()
        return jsonify({'error': 'User not found'}), 404
    
    user_dict = dict(user)
    if user_dict.get('password_hash'):
        if not password:
            conn.close()
            return jsonify({'error': 'Password required'}), 401
        password_hash = hashlib.sha256(password.encode()).hexdigest()
        if password_hash != user_dict.get('password_hash'):
            conn.close()
            return jsonify({'error': 'Invalid password'}), 401
    
    client_ip = get_client_ip()
    geo_info = get_geo_info(client_ip)
    conn.execute('UPDATE users SET last_seen = ?, last_ip = ?, last_location = ?, city = ?, country = ?, region = ? WHERE user_id = ?',
                 (datetime.datetime.now().isoformat(), client_ip, geo_info.get('full', ''), geo_info.get('city', ''), geo_info.get('country', ''), geo_info.get('region', ''), user_id))
    conn.commit()
    
    messages = conn.execute('SELECT message_id as id, sender, text, file_info as file, timestamp FROM messages WHERE user_id = ? ORDER BY timestamp ASC', (user_id,)).fetchall()
    result = []
    for msg in messages:
        msg_dict = dict(msg)
        if msg_dict.get('file'):
            try:
                msg_dict['file'] = json.loads(msg_dict['file'])
            except:
                pass
        result.append(msg_dict)
    conn.close()
    return jsonify({'user_id': user_id, 'profile': user_dict, 'history': result})

@app.route('/api/send_message', methods=['POST', 'OPTIONS'])
def send_message():
    if request.method == 'OPTIONS':
        return '', 200
    data = request.json
    user_id = data.get('user_id')
    message = data.get('message')
    sender = data.get('sender', 'user')
    msg_id = str(uuid.uuid4())
    text = message.get('text', '')
    timestamp = datetime.datetime.now().isoformat()
    conn = get_db()
    conn.execute('INSERT INTO messages (user_id, message_id, sender, text, timestamp, is_read) VALUES (?, ?, ?, ?, ?, ?)',
                 (user_id, msg_id, sender, text, timestamp, 0 if sender == 'user' else 1))
    conn.commit()
    conn.close()
    return jsonify({'id': msg_id, 'sender': sender, 'text': text, 'timestamp': timestamp})

@app.route('/api/edit_message', methods=['PUT', 'OPTIONS'])
def edit_message():
    if request.method == 'OPTIONS':
        return '', 200
    data = request.json
    user_id = data.get('user_id')
    message_id = data.get('message_id')
    new_text = data.get('new_text')
    conn = get_db()
    conn.execute('UPDATE messages SET text = ?, is_edited = 1, edited_at = ? WHERE user_id = ? AND message_id = ?',
                 (new_text, datetime.datetime.now().isoformat(), user_id, message_id))
    conn.commit()
    conn.close()
    return jsonify({'success': True})

@app.route('/api/delete_message', methods=['DELETE', 'OPTIONS'])
def delete_message():
    if request.method == 'OPTIONS':
        return '', 200
    data = request.json
    user_id = data.get('user_id')
    message_id = data.get('message_id')
    conn = get_db()
    conn.execute('DELETE FROM messages WHERE user_id = ? AND message_id = ?', (user_id, message_id))
    conn.commit()
    conn.close()
    return jsonify({'success': True})

@app.route('/api/set_password', methods=['POST', 'OPTIONS'])
def set_password():
    if request.method == 'OPTIONS':
        return '', 200
    data = request.json
    user_id = data.get('user_id')
    password = data.get('password')
    confirm = data.get('confirm')
    if not password or password != confirm or len(password) < 4:
        return jsonify({'error': 'Invalid password'}), 400
    password_hash = hashlib.sha256(password.encode()).hexdigest()
    conn = get_db()
    conn.execute('UPDATE users SET password_hash = ? WHERE user_id = ?', (password_hash, user_id))
    conn.commit()
    conn.close()
    return jsonify({'success': True})

@app.route('/api/upload_file', methods=['POST', 'OPTIONS'])
def upload_file():
    if request.method == 'OPTIONS':
        return '', 200
    user_id = request.form.get('user_id')
    file = request.files.get('file')
    sender = request.form.get('sender', 'user')
    if not file:
        return jsonify({'error': 'No file'}), 400
    file_id = str(uuid.uuid4())
    original_filename = file.filename
    extension = original_filename.split('.')[-1] if '.' in original_filename else ''
    saved_filename = f"{file_id}.{extension}" if extension else file_id
    file_path = os.path.join(UPLOAD_FOLDER, saved_filename)
    file.save(file_path)
    file_info = {
        'id': file_id, 'filename': original_filename, 'saved_name': saved_filename,
        'url': f'/api/file/{file_id}', 'preview_url': f'/api/file/preview/{file_id}',
        'size': os.path.getsize(file_path), 'type': file.content_type
    }
    msg_id = str(uuid.uuid4())
    timestamp = datetime.datetime.now().isoformat()
    conn = get_db()
    conn.execute('INSERT INTO messages (user_id, message_id, sender, text, file_info, timestamp, is_read) VALUES (?, ?, ?, ?, ?, ?, ?)',
                 (user_id, msg_id, sender, '', json.dumps(file_info), timestamp, 0 if sender == 'user' else 1))
    conn.commit()
    conn.close()
    return jsonify({'id': msg_id, 'sender': sender, 'file': file_info, 'timestamp': timestamp})

@app.route('/api/file/<file_id>')
def get_file(file_id):
    for filename in os.listdir(UPLOAD_FOLDER):
        if filename.startswith(file_id):
            return send_from_directory(UPLOAD_FOLDER, filename)
    return jsonify({'error': 'File not found'}), 404

@app.route('/api/file/preview/<file_id>')
def preview_file(file_id):
    for filename in os.listdir(UPLOAD_FOLDER):
        if filename.startswith(file_id):
            return send_from_directory(UPLOAD_FOLDER, filename)
    return jsonify({'error': 'File not found'}), 404

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8000, debug=False)
