from flask import Flask, render_template, request, redirect, url_for, session, flash, send_file, jsonify
import sqlite3
from datetime import datetime
from io import BytesIO
from fpdf import FPDF
import time
import socket
import threading
import queue
import json
import logging
from user_management import user_manager

# Logging ayarları
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

app = Flask(__name__)
app.secret_key = 'çok-gizli-bir-anahtar'

# TCP Bağlantı yöneticisi
class TCPConnectionManager:
    def __init__(self):
        self.server_socket = None
        self.client_connections = {}
        self.connected_device_ips = {}
        self.device_response_status = {}
        self.command_responses = {}  # Komut yanıtlarını saklamak için
        self.data_queue = queue.Queue()
        self.running = False
        self.server_thread = None
        self.client_threads = {}
        self.rate_limit = {}
        self.lock = threading.Lock()
        
    def start_server(self, port=5002):
        try:
            self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            self.server_socket.bind(('0.0.0.0', port))
            self.server_socket.listen(5)
            self.running = True
            
            logger.info(f"TCP Server başlatıldı - Port: {port}")
            
            self.server_thread = threading.Thread(target=self._accept_connections)
            self.server_thread.daemon = True
            self.server_thread.start()
            
        except Exception as e:
            logger.error(f"Server başlatma hatası: {e}")
            
    def _accept_connections(self):
        while self.running:
            try:
                client_socket, address = self.server_socket.accept()
                logger.info(f"Yeni bağlantı: {address}")
                
                client_thread = threading.Thread(
                    target=self._handle_client_connection,
                    args=(client_socket, address)
                )
                client_thread.daemon = True
                client_thread.start()
                
            except Exception as e:
                if self.running:
                    logger.error(f"Bağlantı kabul hatası: {e}")
                    
    def _save_device_info(self, device_id, ip_address, device_data):
        """Cihaz bilgilerini deviceinfo tablosuna kaydet"""
        try:
            conn = get_db_connection()
            
            # Önce mevcut kaydı kontrol et
            existing = conn.execute('SELECT id FROM deviceinfo WHERE device_id = ?', (device_id,)).fetchone()
            
            # Firmware bilgisini al
            firmware_version = device_data.get('version', 'N/A')
            
            if existing:
                # Mevcut kaydı güncelle
                conn.execute('''
                    UPDATE deviceinfo 
                    SET ip_address = ?, device_data = ?, firmware_version = ?, last_update = CURRENT_TIMESTAMP, status = 'online'
                    WHERE device_id = ?
                ''', (ip_address, json.dumps(device_data), firmware_version, device_id))
            else:
                # Yeni kayıt ekle
                conn.execute('''
                    INSERT INTO deviceinfo (device_id, ip_address, device_data, firmware_version, status)
                    VALUES (?, ?, ?, ?, 'online')
                ''', (device_id, ip_address, json.dumps(device_data), firmware_version))
            
            conn.commit()
            conn.close()
            logger.info(f"Device info kaydedildi: {device_id}")
            
        except Exception as e:
            logger.error(f"Device info kaydetme hatası: {e}")
            
    def _update_device_status(self, device_id, status):
        """Cihaz durumunu güncelle"""
        try:
            conn = get_db_connection()
            conn.execute('''
                UPDATE deviceinfo 
                SET status = ?, last_update = CURRENT_TIMESTAMP
                WHERE device_id = ?
            ''', (status, device_id))
            conn.commit()
            conn.close()
            logger.info(f"Device {device_id} durumu güncellendi: {status}")
        except Exception as e:
            logger.error(f"Device durum güncelleme hatası: {e}")
                    
    def _handle_client_connection(self, client_socket, address):
        device_id = None
        try:
            logger.info(f"Client bağlantısı işleniyor: {address}")
            
            # getdeviceinfo gönder
            client_socket.send("getdeviceinfo".encode('utf-8'))
            client_socket.settimeout(5.0)
            data = client_socket.recv(1024)
            
            if data:
                response = data.decode('utf-8').strip()
                logger.info(f"getdeviceinfo yanıtı: {response}")
                
                try:
                    json_response = json.loads(response)
                    device_id = json_response.get('deviceid')
                    
                    if device_id:
                        with self.lock:
                            self.client_connections[device_id] = client_socket
                            self.connected_device_ips[device_id] = address[0]
                        self._start_response_tracking(device_id)
                        # İlk bağlantıda response'u kaydet
                        self._record_device_response(device_id)
                        # Cihaz bilgilerini kaydet
                        self._save_device_info(device_id, address[0], json_response)
                        # getdeviceinfo yanıtını json_data_logs'a da kaydet
                        self._save_json_log(device_id, address[0], json_response, "getdeviceinfo")
                        logger.info(f"Device ID doğrulandı: {device_id}")
                        
                        # Dinleme döngüsü
                        client_socket.settimeout(None)
                        while self.running and device_id in self.client_connections:
                            try:
                data = client_socket.recv(1024)
                if not data:
                    break
                                self._process_incoming_data(data, address, device_id)
                            except Exception as e:
                                logger.error(f"Veri alma hatası: {e}")
                                break
                except json.JSONDecodeError:
                    logger.warning(f"Geçersiz JSON: {response}")
                
        except Exception as e:
            logger.error(f"Client bağlantı hatası: {e}")
        finally:
            # Bağlantı kesildiğinde temizlik yap
            if device_id:
                with self.lock:
                    if device_id in self.client_connections:
                        del self.client_connections[device_id]
                    if device_id in self.connected_device_ips:
                        del self.connected_device_ips[device_id]
                # Cihaz durumunu offline yap
                self._update_device_status(device_id, 'offline')
                logger.info(f"Device {device_id} bağlantısı kesildi")
            
            try:
            client_socket.close()
            except:
                pass
            
    def _process_incoming_data(self, data, address, device_id=None):
        try:
            message = data.decode('utf-8').strip()
            logger.info(f"Gelen veri: {message}")
            
            if device_id:
                self._record_device_response(device_id)
                
                # Komut yanıtlarını kontrol et
                logger.info(f"Cihaz {device_id} yanıtı kontrol ediliyor: {message}")
                if 'setok' in message.lower():
                    self.command_responses[device_id] = {'status': 'success', 'message': 'Komut başarıyla uygulandı'}
                    logger.info(f"Cihaz {device_id} komut yanıtı: BAŞARILI - setok")
                elif 'setfail' in message.lower():
                    self.command_responses[device_id] = {'status': 'error', 'message': 'Komut uygulanamadı'}
                    logger.info(f"Cihaz {device_id} komut yanıtı: BAŞARISIZ - setfail")
                elif 'saveok' in message.lower():
                    self.command_responses[device_id] = {'status': 'success', 'message': 'Ayarlar başarıyla kaydedildi'}
                    logger.info(f"Cihaz {device_id} komut yanıtı: KAYDEDİLDİ - saveok")
                elif 'savefailed' in message.lower():
                    self.command_responses[device_id] = {'status': 'error', 'message': 'Ayarlar kaydedilemedi'}
                    logger.info(f"Cihaz {device_id} komut yanıtı: KAYDEDİLEMEDİ - savefailed")
                elif 'ok' in message.lower() and len(message.strip()) <= 10:
                    self.command_responses[device_id] = {'status': 'success', 'message': 'Komut başarıyla uygulandı'}
                    logger.info(f"Cihaz {device_id} komut yanıtı: BAŞARILI - ok")
                elif 'fail' in message.lower() and len(message.strip()) <= 10:
                    self.command_responses[device_id] = {'status': 'error', 'message': 'Komut uygulanamadı'}
                    logger.info(f"Cihaz {device_id} komut yanıtı: BAŞARISIZ - fail")
                
            try:
                parsed_data = json.loads(message)
                self._save_general_json_data(parsed_data, address)
            except json.JSONDecodeError:
                self._save_simple_access_log(message, address)
                
        except Exception as e:
            logger.error(f"Veri işleme hatası: {e}")
            
    def _save_json_log(self, device_id, ip_address, data, data_type):
        """Cihazdan gelen JSON verileri json_data_logs tablosuna kaydet"""
        try:
            conn = get_db_connection()
            conn.execute('''
                CREATE TABLE IF NOT EXISTS json_data_logs (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    data_type TEXT,
                    json_data TEXT,
                    source_ip TEXT,
                    received_at DATETIME DEFAULT CURRENT_TIMESTAMP
                )
            ''')
            
            json_string = json.dumps(data, ensure_ascii=False, indent=2)
            conn.execute('''
                INSERT INTO json_data_logs (data_type, json_data, source_ip)
                VALUES (?, ?, ?)
            ''', (data_type, json_string, ip_address))
            
            conn.commit()
            conn.close()
            logger.info(f"JSON log kaydedildi: {data_type} - {device_id}")
            
        except Exception as e:
            logger.error(f"JSON log kayıt hatası: {e}")
    
    def _save_general_json_data(self, data, address):
        try:
            conn = get_db_connection()
            conn.execute('''
                CREATE TABLE IF NOT EXISTS json_data_logs (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    data_type TEXT,
                    json_data TEXT,
                    source_ip TEXT,
                    received_at DATETIME DEFAULT CURRENT_TIMESTAMP
                )
            ''')
            
            json_string = json.dumps(data, ensure_ascii=False, indent=2)
            conn.execute('''
                INSERT INTO json_data_logs (data_type, json_data, source_ip)
                VALUES (?, ?, ?)
            ''', ('general_json', json_string, address[0]))
            
            conn.commit()
            conn.close()
            
        except Exception as e:
            logger.error(f"JSON veri kayıt hatası: {e}")
    
    def _save_simple_access_log(self, message, address):
        try:
                conn = get_db_connection()
                conn.execute('''
                    INSERT INTO gecisler (ad, bolge, gecis_turu, notlar, giris_durumu, zaman)
                    VALUES (?, ?, ?, ?, ?, ?)
                ''', (
                'TCP Cihaz',
                    'Genel',
                'ACCESS_TCPCLIENT',
                f'Mesaj: {message} - IP: {address[0]}',
                'GIRIS_YAPILDI',
                datetime.now().strftime('%Y-%m-%d %H:%M:%S')
                ))
                
                conn.commit()
                conn.close()
                
        except Exception as e:
            logger.error(f"Basit log kayıt hatası: {e}")
    
    def _start_response_tracking(self, device_id):
        device_id_str = str(device_id)
        if device_id_str not in self.device_response_status:
            self.device_response_status[device_id_str] = {
                'last_response': None,
                'failed_attempts': 0,
                'last_ping_time': time.time()
            }
        else:
            self.device_response_status[device_id_str]['last_ping_time'] = time.time()
    
    def _record_device_response(self, device_id):
        device_id_str = str(device_id)
        if device_id_str not in self.device_response_status:
            self.device_response_status[device_id_str] = {
                'last_response': None,
                'failed_attempts': 0,
                'last_ping_time': time.time()
            }
        self.device_response_status[device_id_str]['last_response'] = time.time()
        self.device_response_status[device_id_str]['failed_attempts'] = 0
    
    def is_device_connected(self, device_id):
        device_id_str = str(device_id)
        
        # Eğer cihaz client_connections'da varsa, bağlı kabul et
        if device_id_str in self.client_connections:
            return True
            
        # Eğer device_response_status'da varsa ve son yanıt 30 saniye içindeyse bağlı kabul et
        if device_id_str in self.device_response_status:
            last_response = self.device_response_status[device_id_str].get('last_response')
            if last_response:
                now = time.time()
                time_diff = now - last_response
                if time_diff < 30:
                    return True
                
        return False
    
    def send_command_to_device(self, device_id, command_string):
        """Cihaza komut gönderir ve yanıt bekler"""
        try:
            if device_id not in self.connected_device_ips:
                logger.error(f"Cihaz {device_id} bağlı değil")
                return False
            
            ip_address = self.connected_device_ips[device_id]
            
            # Cihazın socket'ini bul
            device_socket = None
            for client_socket in self.client_connections.values():
                # client_socket bir socket objesi, address bilgisi için getpeername() kullan
                try:
                    client_address = client_socket.getpeername()[0]
                    if client_address == ip_address:
                        device_socket = client_socket
                        break
                except:
                    continue
            
            if not device_socket:
                logger.error(f"Cihaz {device_id} socket'i bulunamadı")
                return False
            
            # Komut yanıtını temizle
            self.command_responses[device_id] = None
            logger.info(f"Komut yanıtı temizlendi: {device_id}")
            
            # Komutu gönder
            command_bytes = command_string.encode('utf-8')
            device_socket.send(command_bytes)
            
            logger.info(f"Komut gönderildi: {device_id} -> {command_string}")
            return True
            
            except Exception as e:
            logger.error(f"Komut gönderme hatası: {e}")
            return False
    
    def get_command_response(self, device_id, timeout=15):
        """Komut yanıtını alır"""
        start_time = time.time()
        logger.info(f"Komut yanıtı bekleniyor: {device_id}, timeout: {timeout}")
        while time.time() - start_time < timeout:
            if device_id in self.command_responses and self.command_responses[device_id] is not None:
                response = self.command_responses[device_id]
                self.command_responses[device_id] = None  # Yanıtı temizle
                logger.info(f"Komut yanıtı alındı: {device_id} -> {response}")
                return response
            time.sleep(0.2)  # Polling süresini artır
        logger.warning(f"Komut yanıtı timeout: {device_id}")
        return None
                
    def stop(self):
        logger.info("TCP Connection Manager durduruluyor...")
        self.running = False
        
        if self.server_socket:
            try:
                self.server_socket.close()
            except Exception as e:
                logger.error(f"Server socket kapatma hatası: {e}")
            
        for device_id, client_socket in self.client_connections.items():
            try:
                client_socket.close()
            except Exception as e:
                logger.error(f"Client socket kapatma hatası: {e}")
        
        self.client_connections.clear()
        self.client_threads.clear()
        self.connected_device_ips.clear()
        self.device_response_status.clear()
        
        logger.info("TCP Connection Manager durduruldu")

# Global TCP Manager instance
tcp_manager = TCPConnectionManager()

def get_db_connection():
    conn = sqlite3.connect('data.db')
    conn.row_factory = sqlite3.Row
    return conn

def get_locale():
    return session.get('dil', 'tr')

def _(key):
    lang = get_locale()
    return TRANSLATIONS.get(lang, TRANSLATIONS['tr']).get(key, key)

@app.context_processor
def inject_translations():
    return dict(_=_)

# Çeviri sözlükleri
TRANSLATIONS = {
    'tr': {
        'login_success': 'Başarıyla giriş yaptınız!',
        'device_updated_successfully': 'Cihaz başarıyla güncellendi!',
        'device_update_error': 'Cihaz güncellenirken hata oluştu',
        'required_fields_missing': 'Lütfen tüm zorunlu alanları doldurun',
        'device_not_found': 'Cihaz bulunamadı!',
        'device_deleted_successfully': 'Cihaz başarıyla silindi!',
        'device_delete_error': 'Cihaz silinirken hata oluştu',
        'back_to_devices': 'Cihazlara Dön',
        'access_logs': 'Geçiş Kayıtları',
        'logout': 'Çıkış',
        'filter': 'Filtrele',
        'download_pdf': 'PDF İndir',
        'requests': 'İstekler',
        'user_add': 'Ekle',
        'user_edit': 'Düzenle',
        'index': 'Index',
        'name': 'Ad',
        'region': 'Bölge',
        'access_type': 'Geçiş Türü',
        'note': 'Not',
        'status': 'Giriş Durumu',
        'time': 'Zaman',
        'actions': 'İşlem',
        'language': 'Dil',
        'turkish': 'Türkçe',
        'english': 'İngilizce',
        'GIRIS_YAPILDI': 'Giriş Yapıldı',
        'GIRIS_YAPILMADI': 'Giriş Yapılmadı',
        'IZIN_VERILMEDI': 'İzin Verilmedi',
        'ACCESS_NFC': 'NFC Kart',
        'ACCESS_BUTTON': 'Buton',
        'ACCESS_TCPSERVER': 'TCP Sunucu',
        'ACCESS_TCPCLIENT': 'TCP İstemci',
        'ACCESS_BLE': 'Bluetooth (BLE)',
        'login_username': 'E-posta',
        'login_password': 'Şifre',
        'login_button': 'Giriş Yap',
        'login_placeholder_user': 'E-posta adresiniz',
        'login_placeholder_pass': 'Şifreniz',
        'login_subtitle': 'iAccess Terminal Yönetimi',
        'register_title': 'Kayıt Ol',
        'register_subtitle': 'Hesap Oluştur',
        'register_button': 'Kayıt Ol',
        'register_fullname': 'Ad Soyad',
        'register_email': 'E-posta Adresi',
        'register_company': 'Şirket (Opsiyonel)',
        'register_phone': 'Telefon (Opsiyonel)',
        'register_password': 'Şifre',
        'register_confirm_password': 'Şifre Tekrar',
        'register_terms': 'Kullanım şartlarını kabul ediyorum',
        'register_success': 'Kayıt başarılı! Şimdi giriş yapabilirsiniz.',
        'register_error': 'Kayıt hatası',
        'login_error': 'Giriş hatası',
        'users_title': 'Kullanıcılar',
        'back': 'Geri',
        'users_username': 'Kullanıcı Adı',
        'users_fullname': 'Ad Soyad',
        'users_region': 'Yetki Bölgesi',
        'users_status': 'Aktiflik Durumu',
        'edit': 'Düzenle',
        'delete': 'Sil',
        'users_delete_confirm': 'Kullanıcı silinsin mi?',
        'active': 'Aktif',
        'inactive': 'Pasif',
        'save': 'Kaydet',
        'cancel': 'İptal',
        'device_add': 'Cihaz Ekle',
        'device_add_title': 'Cihaz Ekle',
        'device_name': 'Cihaz Adı',
        'device_serial': 'Seri Numarası',
        'device_tcp_type': 'TCP Tipi',
        'device_tcp_server': 'TCP Server',
        'device_tcp_client': 'TCP Client',
        'device_ip': 'IP Adresi',
        'filter_placeholder': 'Filtrele...',
        'welcome_message': 'Hoş geldiniz',
        'dashboard': 'Ana Sayfa',
        'devices': 'Cihazlar',
        'reports': 'Raporlar',
        'settings': 'Ayarlar',
        'profile': 'Profil',
        'total_devices': 'Toplam Cihaz',
        'total_access': 'Toplam Geçiş',
        'already_have_account': 'Zaten hesabınız var mı',
        'recent_activity': 'Son Aktiviteler',
        'no_data': 'Veri bulunamadı',
        'loading': 'Yükleniyor...',
        'error': 'Hata',
        'success': 'Başarılı',
        'warning': 'Uyarı',
        'info': 'Bilgi',
        'user_not_found': 'Kullanıcı bulunamadı',
        'account_inactive': 'Hesabınız aktif değil',
        'wrong_password': 'Hatalı şifre',
        'invalid_email_format': 'Geçersiz email formatı',
        'password_too_short': 'Şifre en az 6 karakter olmalıdır',
        'email_already_exists': 'Bu email adresi zaten kayıtlı',
        'registration_success': 'Kayıt başarılı! Şimdi giriş yapabilirsiniz.',
        'registration_error': 'Kayıt hatası',
        'full_name_required': 'Ad soyad alanı zorunludur',
        'email_required': 'E-posta alanı zorunludur',
        'passwords_dont_match': 'Şifreler eşleşmiyor',
        'device_add_subtitle': 'Yeni cihaz eklemek için aşağıdaki bilgileri doldurun',
        'device_name_placeholder': 'Örn: Giriş Terminali 1',
        'device_serial_placeholder': 'Örn: SN123456789',
        'device_tcp_select': 'TCP tipini seçin',
        'device_type_info': 'Cihaz Tipi Bilgisi',
        'device_client_info': 'Client cihazlar otomatik olarak sunucuya bağlanır ve veri gönderir.',
        'device_server_info': 'Server cihazlar bağlantıları kabul eder ve veri alır.',
        'device_ip_placeholder': 'Örn: 192.168.1.100',
        'device_ip_required': 'Client cihazlar için IP adresi gereklidir',
        'device_info': 'Cihaz Bilgisi',
        'server_status': 'Sunucu Durumu',
        'tcp_server': 'TCP Sunucu',
        'device_polling': 'Cihaz Polling',
        'auto_connect': 'Otomatik Bağlantı',
        'port': 'Port',
        'refresh_status': 'Durumu Yenile',
        'connection_status': 'Bağlantı Durumu',
        'connect': 'Bağlan',
        'disconnect': 'Kes',
        'send_message': 'Mesaj Gönder',
        'server_mode': 'Sunucu Modu',
        'add_device': 'Cihaz Ekle',
        'send_message_to_device': 'Cihaza Mesaj Gönder',
        'message': 'Mesaj',
        'message_placeholder': 'Gönderilecek mesajı yazın...',
        'send': 'Gönder',
        'unknown': 'Bilinmiyor',
        'connected': 'Bağlı',
        'disconnected': 'Bağlı Değil',
        'manual_status_update': 'Manuel durum güncellemesi yapılıyor...',
        'status_update_started': 'Durum güncellemesi başlatılıyor...',
        'status_update_error': 'Durum güncelleme hatası',
        'confirm_connect_device': 'Cihazına bağlanmak istediğinizden emin misiniz',
        'confirm_disconnect_device': 'Cihaz bağlantısını kesmek istediğinizden emin misiniz?',
        'disconnect_result': 'Bağlantı kesme sonucu',
        'disconnect_success': 'Bağlantı başarıyla kesildi!',
        'disconnect_error': 'Bağlantı kesme hatası',
        'please_enter_message': 'Lütfen bir mesaj yazın!',
        'device_id_not_found': 'Cihaz ID bulunamadı!',
        'device_edit_title': 'Cihaz Düzenle',
        'device_edit_subtitle': 'Cihaz bilgilerini düzenleyin',
        'update': 'Güncelle',
        'confirm_delete_device': 'Bu cihazı silmek istediğinizden emin misiniz?',
        'device_added_successfully': 'Cihaz başarıyla eklendi!',
        'device_serial_exists': 'Bu seri numarasına sahip bir cihaz zaten mevcut!',
        'json_logs': 'JSON Logları',
        'total_logs': 'Toplam Log',
        'device_data': 'Cihaz Verisi',
        'sensor_data': 'Sensör Verisi',
        'no_json_logs': 'JSON Logu Bulunamadı',
        'no_json_logs_description': 'Henüz hiç JSON veri alınmamış. Cihazlarınızı kontrol edin.',
        'go_to_devices': 'Cihazlara Git',
        'device_id_label': 'Cihaz Kimlik Numarası (Device ID)',
        'device_name_label': 'Cihaz Adı (Tanımlayıcı İsim)',
        'device_type_label': 'Cihaz Tipi (TCP Bağlantı Türü)',
        'device_ip_label': 'Cihaz IP Adresi (Ağ Adresi)',
        'device_serial_label': 'Cihaz Seri Numarası (Benzersiz Kimlik)',
        'device_name_placeholder': 'Örn: Ana Giriş Kapısı Terminal 1',
        'device_ip_placeholder': 'Örn: 192.168.1.100 (IPv4 Adresi)',
        'serial_number_readonly': 'Seri numarası değiştirilemez. Bu, cihazın benzersiz kimliğidir.',
        'server_ip_readonly': 'TCP Server modunda IP adresi değiştirilemez. Cihaz sunucuya bağlanacaktır.',
        'device_info_title': 'Cihaz Bilgileri',
        'device_info_subtitle': 'Cihazlardan gelen detaylı bilgiler',
        'device_info_filter': 'Cihaz Filtresi',
        'device_info_all': 'Tüm Cihazlar',
        'device_info_refresh': 'Yenile',
        'device_info_id': 'ID',
        'device_info_name': 'Cihaz Adı',
        'device_info_device_id': 'Cihaz ID',
        'device_info_serial': 'Seri No',
        'device_info_firmware': 'Yazılım',
        'device_info_ip': 'IP Adresi',
        'device_info_status': 'Durum',
        'device_info_last_update': 'Son Güncelleme',
        'device_info_actions': 'İşlemler',
        'device_info_view': 'Detay',
        'device_info_no_data': 'Henüz Cihaz Bilgisi Yok',
        'device_info_no_data_desc': 'Cihazlardan gelen bilgiler burada görüntülenecek.',
        'device_info_details': 'Cihaz Detayları',
        'device_info_close': 'Kapat',
        'device_info_online': 'Çevrimiçi',
        'device_info_offline': 'Çevrimdışı',
        'device_info_unknown': 'Bilinmiyor',
        'device_update_failed': 'Cihaz güncellenemedi',
        'forgot': 'unutuldu',
        'reset_password': 'Şifre Sıfırla',
        'active_devices': 'Aktif Cihazlar',
        'recent_count': 'Son Aktiviteler',
        'total_devices': 'Toplam Cihaz',
        'total_access': 'Toplam Geçiş',
    },
    'en': {
        'login_success': 'Successfully signed in!',
        'device_updated_successfully': 'Device updated successfully!',
        'device_update_error': 'Error updating device',
        'required_fields_missing': 'Please fill in all required fields',
        'device_not_found': 'Device not found!',
        'device_deleted_successfully': 'Device deleted successfully!',
        'device_delete_error': 'Error deleting device',
        'back_to_devices': 'Back to Devices',
        'access_logs': 'Access Logs',
        'logout': 'Logout',
        'filter': 'Filter',
        'download_pdf': 'Download PDF',
        'requests': 'Requests',
        'user_add': 'Add',
        'user_edit': 'Edit',
        'index': 'Index',
        'name': 'Name',
        'region': 'Region',
        'access_type': 'Access Type',
        'note': 'Note',
        'status': 'Status',
        'time': 'Time',
        'actions': 'Actions',
        'language': 'Language',
        'turkish': 'Turkish',
        'english': 'English',
        'GIRIS_YAPILDI': 'Access Granted',
        'GIRIS_YAPILMADI': 'Access Not Granted',
        'IZIN_VERILMEDI': 'Access Denied',
        'ACCESS_NFC': 'NFC Card',
        'ACCESS_BUTTON': 'Button',
        'ACCESS_TCPSERVER': 'TCP Server',
        'ACCESS_TCPCLIENT': 'TCP Client',
        'ACCESS_BLE': 'Bluetooth (BLE)',
        'login_username': 'Email',
        'login_password': 'Password',
        'login_button': 'Sign In',
        'login_placeholder_user': 'Your email address',
        'login_placeholder_pass': 'Your password',
        'login_subtitle': 'iAccess Terminal Management',
        'register_title': 'Register',
        'register_subtitle': 'Create Account',
        'register_button': 'Register',
        'register_fullname': 'Full Name',
        'register_email': 'Email Address',
        'register_company': 'Company (Optional)',
        'register_phone': 'Phone (Optional)',
        'register_password': 'Password',
        'register_confirm_password': 'Confirm Password',
        'register_terms': 'I accept the terms of use',
        'register_success': 'Registration successful! You can now sign in.',
        'register_error': 'Registration error',
        'login_error': 'Login error',
        'users_title': 'Users',
        'back': 'Back',
        'users_username': 'Username',
        'users_fullname': 'Full Name',
        'users_region': 'Region',
        'users_status': 'Status',
        'edit': 'Edit',
        'delete': 'Delete',
        'users_delete_confirm': 'Delete this user?',
        'active': 'Active',
        'inactive': 'Inactive',
        'save': 'Save',
        'cancel': 'Cancel',
        'device_add': 'Add Device',
        'device_add_title': 'Add Device',
        'device_name': 'Device Name',
        'device_serial': 'Serial Number',
        'device_tcp_type': 'TCP Type',
        'device_tcp_server': 'TCP Server',
        'device_tcp_client': 'TCP Client',
        'device_ip': 'IP Address',
        'filter_placeholder': 'Filter...',
        'welcome_message': 'Welcome',
        'dashboard': 'Dashboard',
        'devices': 'Devices',
        'reports': 'Reports',
        'settings': 'Settings',
        'profile': 'Profile',
        'total_devices': 'Total Devices',
        'total_access': 'Total Access',
        'already_have_account': 'Already have an account?',
        'recent_activity': 'Recent Activity',
        'no_data': 'No data found',
        'loading': 'Loading...',
        'error': 'Error',
        'success': 'Success',
        'warning': 'Warning',
        'info': 'Info',
        'user_not_found': 'User not found',
        'account_inactive': 'Your account is not active',
        'wrong_password': 'Wrong password',
        'invalid_email_format': 'Invalid email format',
        'password_too_short': 'Password must be at least 6 characters',
        'email_already_exists': 'This email address is already registered',
        'registration_success': 'Registration successful! You can now sign in.',
        'registration_error': 'Registration error',
        'full_name_required': 'Full name is required',
        'email_required': 'Email is required',
        'passwords_dont_match': 'Passwords do not match',
        'device_add_subtitle': 'Fill in the information below to add a new device',
        'device_name_placeholder': 'Ex: Entry Terminal 1',
        'device_serial_placeholder': 'Ex: SN123456789',
        'device_tcp_select': 'Select TCP type',
        'device_type_info': 'Device Type Information',
        'device_client_info': 'Client devices automatically connect to the server and send data.',
        'device_server_info': 'Server devices accept connections and receive data.',
        'device_ip_placeholder': 'Ex: 192.168.1.100',
        'device_ip_required': 'IP address is required for client devices',
        'device_info': 'Device Info',
        'server_status': 'Server Status',
        'tcp_server': 'TCP Server',
        'device_polling': 'Device Polling',
        'auto_connect': 'Auto Connect',
        'port': 'Port',
        'refresh_status': 'Refresh Status',
        'connection_status': 'Connection Status',
        'connect': 'Connect',
        'disconnect': 'Disconnect',
        'send_message': 'Send Message',
        'server_mode': 'Server Mode',
        'add_device': 'Add Device',
        'send_message_to_device': 'Send Message to Device',
        'message': 'Message',
        'message_placeholder': 'Enter message to send...',
        'send': 'Send',
        'unknown': 'Unknown',
        'connected': 'Connected',
        'disconnected': 'Disconnected',
        'manual_status_update': 'Manual status update in progress...',
        'status_update_started': 'Status update started...',
        'status_update_error': 'Status update error',
        'confirm_connect_device': 'Are you sure you want to connect to device',
        'confirm_disconnect_device': 'Are you sure you want to disconnect the device?',
        'disconnect_result': 'Disconnect result',
        'disconnect_success': 'Connection successfully disconnected!',
        'disconnect_error': 'Disconnect error',
        'please_enter_message': 'Please enter a message!',
        'device_id_not_found': 'Device ID not found!',
        'device_edit_title': 'Edit Device',
        'device_edit_subtitle': 'Edit device information',
        'update': 'Update',
        'confirm_delete_device': 'Are you sure you want to delete this device?',
        'device_added_successfully': 'Device added successfully!',
        'device_serial_exists': 'A device with this serial number already exists!',
        'json_logs': 'JSON Logs',
        'total_logs': 'Total Logs',
        'device_data': 'Device Data',
        'sensor_data': 'Sensor Data',
        'no_json_logs': 'No JSON Logs Found',
        'no_json_logs_description': 'No JSON data has been received yet. Check your devices.',
        'go_to_devices': 'Go to Devices',
        'device_id_label': 'Device ID (Unique Identifier)',
        'device_name_label': 'Device Name (Descriptive Name)',
        'device_type_label': 'Device Type (TCP Connection Type)',
        'device_ip_label': 'Device IP Address (Network Address)',
        'device_serial_label': 'Device Serial Number (Unique ID)',
        'device_name_placeholder': 'Ex: Main Entrance Terminal 1',
        'device_ip_placeholder': 'Ex: 192.168.1.100 (IPv4 Address)',
        'serial_number_readonly': 'Serial number cannot be changed. This is the unique identifier of the device.',
        'server_ip_readonly': 'IP address cannot be changed in TCP Server mode. The device will connect to the server.',
        'device_info_title': 'Device Information',
        'device_info_subtitle': 'Detailed information from devices',
        'device_info_filter': 'Device Filter',
        'device_info_all': 'All Devices',
        'device_info_refresh': 'Refresh',
        'device_info_id': 'ID',
        'device_info_name': 'Device Name',
        'device_info_device_id': 'Device ID',
        'device_info_serial': 'Serial No',
        'device_info_firmware': 'Firmware',
        'device_info_ip': 'IP Address',
        'device_info_status': 'Status',
        'device_info_last_update': 'Last Update',
        'device_info_actions': 'Actions',
        'device_info_view': 'Details',
        'device_info_no_data': 'No Device Information Yet',
        'device_info_no_data_desc': 'Information from devices will be displayed here.',
        'device_info_details': 'Device Details',
        'device_info_close': 'Close',
        'device_info_online': 'Online',
        'device_info_offline': 'Offline',
        'device_info_unknown': 'Unknown',
        'device_update_failed': 'Device update failed',
        'forgot': 'forgot',
        'reset_password': 'Reset Password',
        'active_devices': 'Active Devices',
        'recent_count': 'Recent Activity',
        'total_devices': 'Total Devices',
        'total_access': 'Total Access',
    }
}

def init_deviceinfo_table():
    """Deviceinfo tablosunu oluştur"""
        conn = get_db_connection()
    conn.execute('''
        CREATE TABLE IF NOT EXISTS deviceinfo (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            device_id TEXT NOT NULL,
            ip_address TEXT,
            firmware_version TEXT,
            last_update DATETIME DEFAULT CURRENT_TIMESTAMP,
            device_data TEXT,
            status TEXT DEFAULT 'unknown'
        )
    ''')
    conn.commit()
        conn.close()

@app.route('/set-lang/<lang>')
def set_lang(lang):
    if lang not in TRANSLATIONS:
        lang = 'tr'
    session['dil'] = lang
    return redirect(request.referrer or url_for('home'))

@app.route('/')
def home():
    if not session.get('logged_in'):
        return redirect(url_for('login'))
    
    user_id = session.get('user_id')
    is_admin = session.get('is_admin', False)
    
    # Cihaz sayısını hesapla
    total_devices = 0
    if is_admin:
    conn = get_db_connection()
        # Ana veritabanındaki cihazları say
        data_devices = conn.execute('SELECT COUNT(*) as count FROM cihazlar').fetchone()
        total_devices += data_devices['count'] if data_devices else 0
        
        # Kullanıcı cihazlarını da say
        try:
            from user_management import UserManager
            user_manager = UserManager()
            user_devices = user_manager.get_all_user_devices()
            total_devices += len(user_devices)
        except Exception as e:
            logger.error(f"Kullanıcı cihazları sayma hatası: {e}")
        
        gecisler = conn.execute('SELECT * FROM gecisler ORDER BY id DESC LIMIT 50').fetchall()
        total_access = len(gecisler)
        conn.close()
    else:
        # Normal kullanıcı için sadece kendi cihazlarını say
        try:
            from user_management import UserManager
            user_manager = UserManager()
            user_devices = user_manager.get_user_devices(user_id)
            total_devices = len(user_devices)
        except Exception as e:
            logger.error(f"Kullanıcı cihazları sayma hatası: {e}")
            total_devices = 0
        
        gecisler = user_manager.get_user_access_logs(user_id, limit=50)
        total_access = len(gecisler)
    
    # Aktif cihaz sayısını hesapla
    active_devices = 0
    try:
        if is_admin:
            conn = get_db_connection()
            data_devices = conn.execute('SELECT * FROM cihazlar').fetchall()
    conn.close()
            
            for device in data_devices:
                if tcp_manager.is_device_connected(str(device['id'])):
                    active_devices += 1
            
            # Kullanıcı cihazlarını da kontrol et
            from user_management import UserManager
            user_manager = UserManager()
            user_devices = user_manager.get_all_user_devices()
            for device in user_devices:
                if tcp_manager.is_device_connected(str(device['serial_number'])):
                    active_devices += 1
        else:
            from user_management import UserManager
            user_manager = UserManager()
            user_devices = user_manager.get_user_devices(user_id)
            for device in user_devices:
                if tcp_manager.is_device_connected(str(device['serial_number'])):
                    active_devices += 1
    except Exception as e:
        logger.error(f"Aktif cihaz sayma hatası: {e}")
    
    total_pages = 1
    page = 1
    
    return render_template('dashboard.html', 
                         gecisler=gecisler,
                         page=page,
                         total_pages=total_pages,
                         total_devices=total_devices,
                         total_access=total_access,
                         active_devices=active_devices,
                         recent_count=len(gecisler),
                         user_name=session.get('user_name'),
                         is_admin=is_admin,
                         translations=TRANSLATIONS,
                         current_language=session.get('dil', 'tr'))

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        email = request.form['kullanici']
        password = request.form['sifre']
        
        success, result = user_manager.authenticate_user(email, password)
        
        if success:
            session['logged_in'] = True
            session['user_id'] = result['id']
            session['user_email'] = result['email']
            session['user_name'] = result['full_name']
            session['is_admin'] = result['is_admin']
            flash(_('login_success'), "success")
            return redirect(url_for('home'))
        else:
            flash(_(result), "error")
    
    return render_template('login.html', 
                         translations=TRANSLATIONS,
                         current_language=session.get('dil', 'tr'))

@app.route('/register', methods=['GET', 'POST'])
def register():
    if request.method == 'POST':
        full_name = request.form.get('full_name', '').strip()
        email = request.form.get('email', '').strip()
        password = request.form.get('password', '')
        confirm_password = request.form.get('confirm_password', '')
        company = request.form.get('company', '').strip()
        phone = request.form.get('phone', '').strip()
        
        if not full_name or not email or password != confirm_password:
            flash('Lütfen tüm alanları doğru şekilde doldurun', "error")
            return render_template('register.html', 
                                 translations=TRANSLATIONS,
                                 current_language=session.get('dil', 'tr'))
        
        success, message = user_manager.register_user(email, password, full_name, company, phone)
        
        if success:
            flash(message, "success")
            return redirect(url_for('login'))
        else:
            flash(message, "error")
    
    return render_template('register.html', 
                         translations=TRANSLATIONS,
                         current_language=session.get('dil', 'tr'))

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

@app.route('/users')
def users():
    if not session.get('logged_in'):
        return redirect(url_for('login'))
    conn = get_db_connection()
    users = conn.execute('SELECT * FROM kullanicilar').fetchall()
    conn.close()
    return render_template('users.html', 
                         users=users,
                         translations=TRANSLATIONS,
                         current_language=session.get('dil', 'tr')) 

@app.route('/cihaz-ekle', methods=['GET', 'POST'])
def cihaz_ekle():
    if not session.get('logged_in'):
        return redirect(url_for('login'))
    
    user_id = session.get('user_id')
    is_admin = session.get('is_admin', False)
    
    if request.method == 'POST':
        device_name = request.form['ad']
        serial_no = request.form['seri_no']
        tcp_tipi = request.form['tcp_tipi']
        ip_adresi = request.form.get('ip_adresi', '') if tcp_tipi == 'client' else ''
        
        if is_admin:
        conn = get_db_connection()
            existing_device = conn.execute('SELECT id FROM cihazlar WHERE seri_no = ?', (serial_no,)).fetchone()
            if existing_device:
                flash(_('device_serial_exists'), "error")
                return render_template('cihaz_ekle.html', 
                                     user_name=session.get('user_name'),
                                     is_admin=is_admin,
                                     translations=TRANSLATIONS,
                                     current_language=session.get('dil', 'tr'))
            
            conn.execute('INSERT INTO cihazlar (ad, seri_no, tcp_tipi, ip_adresi) VALUES (?, ?, ?, ?)', 
                        (device_name, serial_no, tcp_tipi, ip_adresi))
        conn.commit()
        conn.close()
            flash(_('device_added_successfully'), "success")
        else:
            success, message = user_manager.add_user_device(
                user_id, device_name, tcp_tipi, ip_adresi, serial_no
            )
            if not success:
                flash(message, "error")
                return render_template('cihaz_ekle.html', 
                                     user_name=session.get('user_name'),
                                     is_admin=is_admin,
                                     translations=TRANSLATIONS,
                                     current_language=session.get('dil', 'tr'))
            flash(message, "success")
        
        return redirect(url_for('devices'))
    
    return render_template('cihaz_ekle.html',
                         user_name=session.get('user_name'),
                         is_admin=is_admin,
                         translations=TRANSLATIONS,
                         current_language=session.get('dil', 'tr'))

@app.route('/download-pdf')
def download_pdf():
    if not session.get('logged_in'):
        return redirect(url_for('login'))
    
    user_id = session.get('user_id')
    is_admin = session.get('is_admin', False)
    
    if is_admin:
    conn = get_db_connection()
        gecisler = conn.execute('SELECT * FROM gecisler ORDER BY id DESC LIMIT 100').fetchall()
    conn.close()
    else:
        gecisler = user_manager.get_user_access_logs(user_id, limit=100)
    
    # PDF oluştur
    pdf = FPDF()
    pdf.add_font('DejaVu', '', 'static/fonts/DejaVuSans.ttf', uni=True)
    pdf.set_font('DejaVu', '', 14)
    pdf.add_page()
    pdf.cell(0, 10, 'Geçiş Kayıtları', ln=1, align='C')
    pdf.set_font('DejaVu', '', 8)
    
    headers = ['ID', 'Ad', 'Bölge', 'Geçiş Türü', 'Not', 'Durum', 'Zaman']
    col_widths = [15, 40, 30, 35, 40, 30, 35]
    
    for i, h in enumerate(headers):
        pdf.cell(col_widths[i], 8, h, border=1, align='C')
    pdf.ln()
    
    for row in gecisler:
        if is_admin:
        values = [
                str(row['id']),
                str(row['ad']),
                str(row.get('bolge', '')),
                str(row['gecis_turu']),
                str(row['notlar']),
                str(row['giris_durumu']),
                str(row['zaman'])
            ]
        else:
            values = [
                str(row.get('id', '')),
                str(row.get('person_name', '')),
                str(row.get('region', '')),
                str(row.get('access_type', '')),
                str(row.get('notes', '')),
                str(row.get('access_status', '')),
                str(row.get('timestamp', ''))
            ]
        
        for v, w in zip(values, col_widths):
            pdf.cell(w, 8, v[:w//8] if len(v) > w//8 else v, border=1)
        pdf.ln()
    
    pdf_buffer = BytesIO()
    pdf.output(pdf_buffer)
    pdf_buffer.seek(0)
    filename = f"gecis_kayitlari_{time.strftime('%Y%m%d_%H%M%S')}.pdf"
    return send_file(pdf_buffer, as_attachment=True, download_name=filename, mimetype='application/pdf')

@app.route('/deviceinfo')
def device_info():
    if not session.get('logged_in'):
        return redirect(url_for('login'))
    
    user_id = session.get('user_id')
    is_admin = session.get('is_admin', False)
    
    logger.info(f"Deviceinfo route çağrıldı - User ID: {user_id}, Admin: {is_admin}")
    
    try:
        if is_admin:
            # Admin için tüm cihaz bilgilerini göster
        conn = get_db_connection()
            device_infos = conn.execute('''
                SELECT di.*, c.ad as device_name 
                FROM deviceinfo di
                LEFT JOIN cihazlar c ON di.device_id = c.id
                ORDER BY di.last_update DESC 
                LIMIT 100
            ''').fetchall()
        conn.close()
            logger.info(f"Admin için {len(device_infos)} cihaz bilgisi bulundu")
        else:
            # Normal kullanıcı için sadece ilk cihazını göster
            from user_management import UserManager
            user_manager = UserManager()
            user_devices = user_manager.get_user_devices(user_id)
            logger.info(f"Kullanıcı {user_id} için {len(user_devices)} cihaz bulundu")
            
            # Sadece ilk cihazı al
            device_infos = []
            if user_devices:
                user_device = user_devices[0]  # İlk cihazı al
                device_id = str(user_device['serial_number'])
                
                # deviceinfo tablosundan firmware ve IP bilgisini al
                firmware_version = 'N/A'
                ip_address = user_device['ip_address']  # Varsayılan olarak user_device'dan al
                try:
    conn = get_db_connection()
                    device_info = conn.execute('''
                        SELECT firmware_version, ip_address FROM deviceinfo 
                        WHERE device_id = ?
                    ''', (device_id,)).fetchone()
    conn.close()
                    
                    if device_info:
                        if device_info['firmware_version']:
                            firmware_version = device_info['firmware_version']
                        if device_info['ip_address']:
                            ip_address = device_info['ip_address']
                except Exception as e:
                    logger.error(f"Device info alma hatası: {e}")
                
                device_info = {
                    'id': user_device['id'],
                    'device_id': user_device['serial_number'],
                    'ip_address': ip_address,
                    'device_name': user_device['device_name'],
                    'firmware_version': firmware_version,
                    'last_update': user_device['created_at'],
                    'status': 'online' if tcp_manager.is_device_connected(device_id) else 'offline'
                }
                device_infos.append(device_info)
            
            logger.info(f"Kullanıcının ilk cihazı deviceinfo formatına çevrildi")
        
        logger.info(f"Toplam {len(device_infos)} cihaz bilgisi döndürülüyor")
        
    except Exception as e:
        logger.error(f"Device info getirme hatası: {e}")
        device_infos = []
    
    return render_template('deviceinfo.html', 
                         device_infos=device_infos,
                         translations=TRANSLATIONS,
                         current_language=session.get('dil', 'tr'))

@app.route('/json-logs')
def json_logs():
    if not session.get('logged_in'):
        return redirect(url_for('login'))
    
    user_id = session.get('user_id')
    is_admin = session.get('is_admin', False)
    
    conn = get_db_connection()
    
    if is_admin:
        json_logs = conn.execute('''
            SELECT * FROM json_data_logs 
            ORDER BY received_at DESC 
            LIMIT 100
        ''').fetchall()
    else:
        # Normal kullanıcı için user_management'den cihaz bilgilerini al
        try:
            from user_management import UserManager
            user_manager = UserManager()
            user_devices = user_manager.get_user_devices(user_id)
            device_serial_numbers = [str(device['serial_number']) for device in user_devices]
            
            if device_serial_numbers:
                placeholders = ','.join(['?' for _ in device_serial_numbers])
                json_logs = conn.execute(f'''
                    SELECT * FROM json_data_logs 
                    WHERE source_ip IN (
                        SELECT DISTINCT ip_address FROM deviceinfo 
                        WHERE device_id IN ({placeholders})
                    )
                    ORDER BY received_at DESC 
                    LIMIT 100
                ''', device_serial_numbers).fetchall()
        else:
                json_logs = []
    except Exception as e:
            logger.error(f"JSON logs getirme hatası: {e}")
            json_logs = []
    
    conn.close()
    
    return render_template('json_logs.html', 
                         json_logs=json_logs,
                         user_name=session.get('user_name'),
                         is_admin=is_admin,
                         translations=TRANSLATIONS,
                         current_language=session.get('dil', 'tr'))

@app.route('/device/edit/user/<device_id>', methods=['GET', 'POST'])
def edit_user_device(device_id):
    if not session.get('logged_in'):
        return redirect(url_for('login'))
    
    user_id = session.get('user_id')
    
    from user_management import UserManager
    user_manager = UserManager()
    
    user_devices = user_manager.get_user_devices(user_id)
    device = None
    
    for dev in user_devices:
        if str(dev['serial_number']) == str(device_id):
            device = dev
            break
    
    if not device:
        flash(_('device_not_found'), 'error')
        return redirect(url_for('devices'))
    
    if request.method == 'POST':
        device_name = request.form.get('device_name', '')
        device_type = request.form.get('device_type', '')
        ip_address = request.form.get('ip_address', '')
        
        if not device_name or not device_type:
            flash(_('device_update_error') + ': ' + _('required_fields_missing'), 'error')
            return redirect(url_for('edit_user_device', device_id=device_id))
        
        try:
            success, message = user_manager.update_user_device(user_id, device_id, device_name, device_type, ip_address)
            if success:
                flash(_('device_updated_successfully'), 'success')
            else:
                flash(_('device_update_error') + f': {message}', 'error')
            return redirect(url_for('devices'))
            except Exception as e:
            flash(_('device_update_error') + f': {e}', 'error')
            return redirect(url_for('edit_user_device', device_id=device_id))
    
    is_connected = tcp_manager.is_device_connected(str(device_id))
    
    return render_template('edit_user_device.html', 
                         device=device,
                         is_connected=is_connected,
                         translations=TRANSLATIONS,
                         current_language=session.get('dil', 'tr'))

@app.route('/device/delete/user/<device_id>')
def delete_user_device(device_id):
    if not session.get('logged_in'):
        return redirect(url_for('login'))
    
    user_id = session.get('user_id')
    
    from user_management import UserManager
    user_manager = UserManager()
    
    try:
        success, message = user_manager.delete_user_device(user_id, device_id)
        
        if success:
            flash(_('device_deleted_successfully'), 'success')
        else:
            flash(_('device_delete_error') + f': {message}', 'error')
            
    except Exception as e:
        logger.error(f"Cihaz silme hatası: {e}")
        flash(_('device_delete_error'), 'error')
    
    return redirect(url_for('devices'))

@app.route('/api/debug/tcp-status')
def debug_tcp_status():
    """TCP Manager durumunu debug için gösterir"""
    if not session.get('logged_in'):
        return jsonify({'error': 'Unauthorized'}), 401
    
    try:
        return jsonify({
            'client_connections': list(tcp_manager.client_connections.keys()),
            'connected_device_ips': dict(tcp_manager.connected_device_ips),
            'device_response_status': {
                k: {
                    'last_response': v.get('last_response'),
                    'failed_attempts': v.get('failed_attempts'),
                    'last_ping_time': v.get('last_ping_time')
                } for k, v in tcp_manager.device_response_status.items()
            },
            'running': tcp_manager.running,
            'server_socket': tcp_manager.server_socket is not None
        })
    except Exception as e:
        logger.error(f"Debug TCP status hatası: {e}")
        return jsonify({'error': str(e)}), 500

@app.route('/api/device/status/<device_id>')
def device_connection_status(device_id):
    """Belirli bir cihazın bağlantı durumunu kontrol eder"""
    if not session.get('logged_in'):
        return jsonify({'error': 'Unauthorized'}), 401
    
    try:
        is_connected = tcp_manager.is_device_connected(device_id)
        device_id_str = str(device_id)
        
        # Cihazın son yanıt zamanını al
        last_response = None
        if device_id_str in tcp_manager.device_response_status:
            last_response = tcp_manager.device_response_status[device_id_str].get('last_response')
        
        return jsonify({
            'device_id': device_id,
            'connected': is_connected,
            'last_response': last_response,
            'in_client_connections': device_id_str in tcp_manager.client_connections,
            'in_response_status': device_id_str in tcp_manager.device_response_status
        })
    except Exception as e:
        logger.error(f"Cihaz durumu kontrol hatası: {e}")
        return jsonify({'error': str(e)}), 500

@app.route('/api/device/status')
def device_status():
    status_list = []
    
    conn = get_db_connection()
    devices = conn.execute('SELECT * FROM cihazlar').fetchall()
    conn.close()
    
    for device in devices:
        device_id_str = str(device['id'])
        is_connected = tcp_manager.is_device_connected(device_id_str)
        status_list.append({
            'id': device_id_str,
            'name': device['ad'],
            'tcp_type': device['tcp_tipi'],
            'ip_address': device['ip_adresi'],
            'connected': is_connected
        })
    
    try:
        from user_management import UserManager
        user_manager = UserManager()
        user_devices = user_manager.get_all_user_devices()
        for user_device in user_devices:
            device_id_str = str(user_device['serial_number'])
            
            existing_device = None
            for existing in status_list:
                if existing['id'] == device_id_str:
                    existing_device = existing
                    break
            
            if existing_device:
                is_connected = tcp_manager.is_device_connected(device_id_str)
                existing_device['connected'] = is_connected
            else:
                is_connected = tcp_manager.is_device_connected(device_id_str)
                status_list.append({
                    'id': device_id_str,
                    'name': f"{user_device['device_name']} (User: {user_device['user_id']})",
                    'tcp_type': user_device['device_type'],
                    'ip_address': user_device['ip_address'],
                    'connected': is_connected
                })
    except Exception as e:
        logger.error(f"Kullanıcı cihazları getirme hatası: {e}")
    
    return {'devices': status_list}

@app.route('/devices')
def devices():
    if not session.get('logged_in'):
        return redirect(url_for('login'))
    
    user_id = session.get('user_id')
    is_admin = session.get('is_admin', False)
    
    from user_management import UserManager
    user_manager = UserManager()
    
    cihazlar = []
    
    if is_admin:
        conn = get_db_connection()
        data_devices = conn.execute('SELECT * FROM cihazlar').fetchall()
        conn.close()
        
        for device in data_devices:
            cihazlar.append({
                'id': device['id'],
                'ad': device['ad'],
                'seri_no': device.get('seri_no'),
                'tcp_tipi': device['tcp_tipi'],
                'ip_adresi': device['ip_adresi'],
                'source': 'data_db'
            })
        
        try:
            user_devices = user_manager.get_all_user_devices()
            for user_device in user_devices:
                device_id = user_device['serial_number']
                existing_device = None
                for existing in cihazlar:
                    if str(existing['id']) == str(device_id):
                        existing_device = existing
                        break
                
                if not existing_device:
                    cihazlar.append({
                        'id': device_id,
                        'ad': user_device['device_name'],
                        'seri_no': device_id,
                        'tcp_tipi': user_device['device_type'],
                        'ip_adresi': user_device['ip_address'],
                        'source': 'users_db'
                    })
        except Exception as e:
            logger.error(f"Kullanıcı cihazları getirme hatası: {e}")
    else:
        user_devices = user_manager.get_user_devices(user_id)
        if user_devices:
            for user_device in user_devices:
                cihazlar.append({
                    'id': user_device['serial_number'],
                    'ad': user_device['device_name'],
                    'seri_no': user_device['serial_number'],
                    'tcp_tipi': user_device['device_type'],
                    'ip_adresi': user_device['ip_address'],
                    'source': 'users_db'
                })
    
    # Cihazların bağlantı durumunu kontrol et ve firmware bilgisini ekle
    for cihaz in cihazlar:
        device_id = str(cihaz['id'])
        cihaz['is_connected'] = tcp_manager.is_device_connected(device_id)
        
        # IP adresini al - önce connected_device_ips'den, sonra deviceinfo'dan
        if device_id in tcp_manager.connected_device_ips:
            cihaz['ip_adresi'] = tcp_manager.connected_device_ips[device_id]
        elif not cihaz.get('ip_adresi') or cihaz.get('ip_adresi') == '':
            # deviceinfo tablosundan IP adresini al
            try:
                conn = get_db_connection()
                device_info = conn.execute('''
                    SELECT ip_address FROM deviceinfo 
                    WHERE device_id = ?
                ''', (device_id,)).fetchone()
                conn.close()
                
                if device_info and device_info['ip_address']:
                    cihaz['ip_adresi'] = device_info['ip_address']
                    logger.info(f"IP adresi deviceinfo'dan alındı: {device_id} -> {device_info['ip_address']}")
            except Exception as e:
                logger.error(f"IP adresi alma hatası: {e}")
        
        # Seri no bilgisini düzelt
        if not cihaz.get('seri_no') and cihaz.get('id'):
            cihaz['seri_no'] = cihaz['id']
        
        # Firmware bilgisini deviceinfo tablosundan al
        try:
            conn = get_db_connection()
            device_info = conn.execute('''
                SELECT firmware_version, ip_address FROM deviceinfo 
                WHERE device_id = ?
            ''', (device_id,)).fetchone()
            conn.close()
            
            if device_info:
                if device_info['firmware_version']:
                    cihaz['firmware_version'] = device_info['firmware_version']
        else:
                    cihaz['firmware_version'] = 'N/A'
            
                # IP adresi yoksa deviceinfo'dan al
                if not cihaz.get('ip_adresi') and device_info['ip_address']:
                    cihaz['ip_adresi'] = device_info['ip_address']
            else:
                cihaz['firmware_version'] = 'N/A'
    except Exception as e:
            logger.error(f"Firmware bilgisi alma hatası: {e}")
            cihaz['firmware_version'] = 'N/A'
    
    return render_template('devices.html', 
                         cihazlar=cihazlar,
                         user_name=session.get('user_name'),
                         is_admin=is_admin,
                         connected_device_ips=tcp_manager.connected_device_ips,
                         translations=TRANSLATIONS,
                         current_language=session.get('dil', 'tr'))

@app.route('/device/settings/<device_id>')
def device_settings(device_id):
    if 'user_id' not in session:
        return redirect(url_for('login'))
    
    user_id = session['user_id']
    
    # Cihaz bilgilerini al
    try:
    conn = get_db_connection()
        device_info = conn.execute('''
            SELECT * FROM cihazlar WHERE id = ?
        ''', (device_id,)).fetchone()
    conn.close()
    
        if not device_info:
            flash('Cihaz bulunamadı!', 'error')
            return redirect(url_for('devices'))
        
        # IP adresini al
        ip_address = 'N/A'
        if str(device_id) in tcp_manager.connected_device_ips:
            ip_address = tcp_manager.connected_device_ips[str(device_id)]
        else:
            try:
    conn = get_db_connection()
                device_info_db = conn.execute('''
                    SELECT ip_address FROM deviceinfo WHERE device_id = ?
                ''', (str(device_id),)).fetchone()
    conn.close()
    
                if device_info_db and device_info_db['ip_address']:
                    ip_address = device_info_db['ip_address']
            except Exception as e:
                logger.error(f"IP adresi alma hatası: {e}")
        
        device_data = {
            'id': str(device_info['id']),
            'device_id': device_info['id'],
            'device_name': device_info['ad'],
            'ip_address': ip_address
        }
        
        return render_template('device_settings.html', device_info=device_data)
        
    except Exception as e:
        logger.error(f"Device settings hatası: {e}")
        flash('Cihaz bilgileri alınırken hata oluştu!', 'error')
        return redirect(url_for('devices'))

@app.route('/api/device_command/<device_id>', methods=['POST'])
def device_command(device_id):
    if 'user_id' not in session:
        return jsonify({'success': False, 'message': 'Unauthorized'}), 401
    
    try:
        data = request.get_json()
        command = data.get('command')
        command_data = data.get('data', {})
        
        if not command:
            return jsonify({'success': False, 'message': 'Komut belirtilmedi'}), 400
        
        # Cihazın kullanıcıya ait olduğunu kontrol et
        user_id = session['user_id']
        conn = get_db_connection()
        device = conn.execute('''
            SELECT * FROM cihazlar WHERE id = ?
        ''', (device_id,)).fetchone()
        conn.close()
        
        if not device:
            return jsonify({'success': False, 'message': 'Cihaz bulunamadı'}), 404
        
        # Cihazın bağlı olup olmadığını kontrol et
        if not tcp_manager.is_device_connected(str(device_id)):
            return jsonify({'success': False, 'message': 'Cihaz bağlı değil'}), 400
        
        # Komutu cihaza gönder
        ip_address = tcp_manager.connected_device_ips.get(str(device_id))
        if not ip_address:
            return jsonify({'success': False, 'message': 'Cihaz IP adresi bulunamadı'}), 400
        
        # JSON komutunu oluştur
        if command == 'setwifissid' and 'setwifipassword' in command_data:
            # WiFi SSID ve password aynı anda gönderiliyor - doğrudan command_data'yı kullan
            json_command = command_data
        elif command == 'setwifissid':
            # Sadece SSID gönderiliyor
            json_command = {command: command_data.get('setwifissid', '')}
        else:
            json_command = {command: command_data}
        command_string = json.dumps(json_command)
        
        # TCP üzerinden komutu gönder
        success = tcp_manager.send_command_to_device(str(device_id), command_string)
        
        if success:
            # Cihazdan yanıt bekle
            response = tcp_manager.get_command_response(str(device_id), timeout=15)
            
            if response:
                if response['status'] == 'success':
                    return jsonify({'success': True, 'message': response['message']})
                else:
                    return jsonify({'success': False, 'message': response['message']}), 400
            else:
                return jsonify({'success': True, 'message': f'{command} komutu gönderildi (yanıt bekleniyor)'})
        else:
            return jsonify({'success': False, 'message': 'Komut gönderilemedi'}), 500
        
    except Exception as e:
        logger.error(f"Device command hatası: {e}")
        return jsonify({'success': False, 'message': f'Hata: {str(e)}'}), 500

@app.route('/api/deviceinfo/<device_id>')
def get_device_info_details(device_id):
    """Cihazdan gelen tüm verileri getir"""
    if not session.get('logged_in'):
        return jsonify({'error': 'Unauthorized'}), 401
    
    user_id = session.get('user_id')
    is_admin = session.get('is_admin', False)
    
    try:
        conn = get_db_connection()
        
        # Önce deviceinfo tablosunda ara
        device_info = conn.execute('''
            SELECT * FROM deviceinfo 
            WHERE device_id = ? 
        ''', (device_id,)).fetchone()
        
        # Eğer deviceinfo'da yoksa, kullanıcı cihazlarında ara
        if not device_info and not is_admin:
            from user_management import UserManager
            user_manager = UserManager()
            user_devices = user_manager.get_user_devices(user_id)
            
            user_device = None
            for dev in user_devices:
                if str(dev['serial_number']) == str(device_id):
                    user_device = dev
                    break
            
            if user_device:
                # Kullanıcı cihazından deviceinfo formatında veri oluştur
                device_info = {
                    'id': user_device['id'],
                    'device_id': user_device['serial_number'],
                    'ip_address': user_device['ip_address'],
                    'firmware_version': 'N/A',
                    'status': 'unknown',
                    'last_update': user_device['created_at'],
                    'device_data': '{}'
                }
            else:
                return jsonify({'success': False, 'message': 'Device not found'}), 404
        elif not device_info:
            return jsonify({'success': False, 'message': 'Device not found'}), 404
        
        # JSON verilerini parse et
        device_data = {}
        if device_info['device_data']:
            try:
                device_data = json.loads(device_info['device_data'])
            except json.JSONDecodeError:
                device_data = {'raw_data': device_info['device_data']}
        
        # Cihazın IP adresini al
        device_ip = None
        if device_info['ip_address']:
            device_ip = device_info['ip_address']
        elif device_id in tcp_manager.connected_device_ips:
            device_ip = tcp_manager.connected_device_ips[device_id]
        
        # Cihazdan gelen JSON loglarını al (sadece getdeviceinfo verilerini öncelikle)
        json_logs = []
        if device_ip:
            # Önce getdeviceinfo verilerini al
            getdeviceinfo_logs = conn.execute('''
                SELECT * FROM json_data_logs 
                WHERE source_ip = ? AND data_type = 'getdeviceinfo'
                ORDER BY received_at DESC 
                LIMIT 10
            ''', (device_ip,)).fetchall()
            
            # Sonra diğer verileri al
            other_logs = conn.execute('''
                SELECT * FROM json_data_logs 
                WHERE source_ip = ? AND data_type != 'getdeviceinfo'
                ORDER BY received_at DESC 
                LIMIT 40
            ''', (device_ip,)).fetchall()
            
            # getdeviceinfo verilerini önce ekle, sonra diğerlerini
            json_logs = list(getdeviceinfo_logs) + list(other_logs)
        
        # JSON loglarını parse et
        parsed_logs = []
        for log in json_logs:
            try:
                log_data = json.loads(log['json_data'])
                parsed_logs.append({
                    'id': log['id'],
                    'data_type': log['data_type'],
                    'json_data': log_data,
                    'source_ip': log['source_ip'],
                    'received_at': log['received_at']
                })
            except json.JSONDecodeError:
                parsed_logs.append({
                    'id': log['id'],
                    'data_type': log['data_type'],
                    'json_data': {'raw_data': log['json_data']},
                    'source_ip': log['source_ip'],
                    'received_at': log['received_at']
                })
        
        conn.close()
        
        # Cihaz bağlantı durumunu kontrol et
        is_connected = tcp_manager.is_device_connected(device_id)
        
        # Detaylı bilgileri hazırla
        detailed_info = {
            'device_info': {
                'id': device_info['id'],
                'device_id': device_info['device_id'],
                'ip_address': device_info['ip_address'] if device_info['ip_address'] else None,
                'firmware_version': device_info['firmware_version'] if device_info['firmware_version'] else 'N/A',
                'status': device_info['status'] if device_info['status'] else 'unknown',
                'last_update': device_info['last_update'] if device_info['last_update'] else None,
                'is_connected': is_connected
            },
            'device_data': device_data,
            'json_logs': parsed_logs,
            'connection_info': {
                'in_client_connections': device_id in tcp_manager.client_connections,
                'in_response_status': device_id in tcp_manager.device_response_status,
                'last_response': None
            }
        }
        
        # Son yanıt zamanını al
        if device_id in tcp_manager.device_response_status:
            last_response = tcp_manager.device_response_status[device_id].get('last_response')
            if last_response:
                detailed_info['connection_info']['last_response'] = datetime.fromtimestamp(last_response).strftime('%Y-%m-%d %H:%M:%S')
        
        return jsonify({
            'success': True,
            'info': detailed_info
        })
        
    except Exception as e:
        logger.error(f"Device info details hatası: {e}")
        return jsonify({'success': False, 'message': str(e)}), 500 

if __name__ == '__main__':
    # Gerekli tabloları oluştur
    init_deviceinfo_table()
    
    try:
        tcp_manager.start_server(port=5002)
        logger.info("TCP Server başlatıldı - Port 5002")
    except Exception as e:
            logger.error(f"TCP Server başlatma hatası: {e}")
    
    logger.info("Uygulama başlatılıyor...")
    app.run(host='0.0.0.0', port=5001, debug=True, use_reloader=False, threaded=False) 