#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Tutku XLine Bot - Renkli Versiyon
Version: 3.3
Author: Sado
Web Panel: https://tutku.jetcozum.xyz
"""

import socket
import ssl
import threading
import time
import re
import json
import os
import sys
import random
import string
from datetime import datetime
from typing import Dict, List, Optional, Tuple, Set
import hashlib
from urllib.parse import parse_qs, unquote
import traceback
from collections import defaultdict
import ipaddress
from http.server import HTTPServer, BaseHTTPRequestHandler

# ====================== RENK SİSTEMİ ======================
class IRCColors:
    """IRC renk kodları"""
    # Temel renkler
    WHITE = "00"
    BLACK = "01"
    DARK_BLUE = "02"
    DARK_GREEN = "03"
    RED = "04"
    DARK_RED = "05"
    DARK_PURPLE = "06"
    ORANGE = "07"
    YELLOW = "08"
    LIGHT_GREEN = "09"
    CYAN = "10"
    LIGHT_CYAN = "11"
    BLUE = "12"
    PURPLE = "13"
    DARK_GRAY = "14"
    LIGHT_GRAY = "15"
    
    # Formatlar
    BOLD = "\x02"
    COLOR = "\x03"
    RESET = "\x0f"
    UNDERLINE = "\x1f"
    REVERSE = "\x16"
    
    # Renk map
    COLOR_MAP = {
        "0": WHITE, "beyaz": WHITE,
        "1": BLACK, "siyah": BLACK,
        "2": DARK_BLUE, "koyu_mavi": DARK_BLUE, "lacivert": DARK_BLUE,
        "3": DARK_GREEN, "koyu_yesil": DARK_GREEN, "koyu_yeşil": DARK_GREEN,
        "4": RED, "kırmızı": RED, "kirmizi": RED,
        "5": DARK_RED, "koyu_kırmızı": DARK_RED, "koyu_kirmizi": DARK_RED,
        "6": DARK_PURPLE, "mor": DARK_PURPLE,
        "7": ORANGE, "turuncu": ORANGE,
        "8": YELLOW, "sarı": YELLOW, "sari": YELLOW,
        "9": LIGHT_GREEN, "açık_yeşil": LIGHT_GREEN, "acik_yesil": LIGHT_GREEN,
        "10": CYAN, "cyan": CYAN,
        "11": LIGHT_CYAN, "açık_cyan": LIGHT_CYAN, "acik_cyan": LIGHT_CYAN,
        "12": BLUE, "mavi": BLUE,
        "13": PURPLE, "açık_mor": PURPLE, "acik_mor": PURPLE,
        "14": DARK_GRAY, "koyu_gri": DARK_GRAY,
        "15": LIGHT_GRAY, "açık_gri": LIGHT_GRAY, "acik_gri": LIGHT_GRAY,
    }
    
    @classmethod
    def colorize(cls, text: str, color_code: str, bg_color: str = None) -> str:
        """Metni renklendir"""
        color = cls.COLOR_MAP.get(str(color_code), cls.RED)
        if bg_color:
            bg = cls.COLOR_MAP.get(str(bg_color), cls.RED)
            return f"{cls.COLOR}{color},{bg}{text}{cls.RESET}"
        return f"{cls.COLOR}{color}{text}{cls.RESET}"
    
    @classmethod
    def bold(cls, text: str) -> str:
        """Kalın yaz"""
        return f"{cls.BOLD}{text}{cls.RESET}"
    
    @classmethod
    def underline(cls, text: str) -> str:
        """Altı çizili yaz"""
        return f"{cls.UNDERLINE}{text}{cls.RESET}"
    
    @classmethod
    def rainbow(cls, text: str, pattern: List[int] = None) -> str:
        """Gökkuşağı efekti"""
        if not pattern:
            pattern = [4, 7, 8, 3, 12, 13, 6]  # Kırmızı, turuncu, sarı, yeşil, mavi, mor
        
        result = ""
        for i, char in enumerate(text):
            if char == " ":
                result += " "
                continue
            color_idx = pattern[i % len(pattern)]
            result += cls.colorize(char, str(color_idx))
        return result
    
    @classmethod
    def get_color_name(cls, color_code: str) -> str:
        """Renk kodundan isim al"""
        color_names = {
            "00": "Beyaz", "01": "Siyah", "02": "Koyu Mavi",
            "03": "Koyu Yesil", "04": "Kirmizi", "05": "Koyu Kirmizi",
            "06": "Mor", "07": "Turuncu", "08": "Sari",
            "09": "Acik Yesil", "10": "Cyan", "11": "Acik Cyan",
            "12": "Mavi", "13": "Acik Mor", "14": "Koyu Gri",
            "15": "Acik Gri"
        }
        return color_names.get(color_code, "Bilinmeyen")

# ====================== TEMA SİSTEMİ ======================
class ThemeSystem:
    """Tema yönetim sistemi"""
    
    THEMES = {
        "default": {
            "success": "03",  # Yeşil
            "error": "04",    # Kırmızı
            "warning": "07",  # Turuncu
            "info": "12",     # Mavi
            "admin": "04",    # Kırmızı
            "oper": "07",     # Turuncu
            "user": "15",     # Açık Gri
            "highlight": "08" # Sarı
        },
        "dark": {
            "success": "09",  # Açık Yeşil
            "error": "05",    # Koyu Kırmızı
            "warning": "07",  # Turuncu
            "info": "11",     # Açık Cyan
            "admin": "13",    # Açık Mor
            "oper": "08",     # Sarı
            "user": "14",     # Koyu Gri
            "highlight": "07" # Turuncu
        },
        "bright": {
            "success": "03",  # Yeşil
            "error": "04",    # Kırmızı
            "warning": "08",  # Sarı
            "info": "12",     # Mavi
            "admin": "06",    # Mor
            "oper": "07",     # Turuncu
            "user": "01",     # Siyah
            "highlight": "04" # Kırmızı
        },
        "rainbow": {
            "success": "09",  # Açık Yeşil
            "error": "04",    # Kırmızı
            "warning": "08",  # Sarı
            "info": "12",     # Mavi
            "admin": "13",    # Açık Mor
            "oper": "07",     # Turuncu
            "user": "15",     # Açık Gri
            "highlight": "06" # Mor
        }
    }
    
    @classmethod
    def apply_theme(cls, theme_name: str) -> Dict:
        """Tema uygula"""
        return cls.THEMES.get(theme_name, cls.THEMES["default"])

# ====================== RATE LIMITER ======================
class RateLimiter:
    """Rate limiting sınıfı"""
    def __init__(self, max_requests=30, time_window=60):
        self.max_requests = max_requests
        self.time_window = time_window
        self.requests = defaultdict(list)
    
    def is_allowed(self, ip_address: str) -> bool:
        """IP adresine göre rate limit kontrolü"""
        now = time.time()
        
        # Eski istekleri temizle
        self.requests[ip_address] = [
            req_time for req_time in self.requests[ip_address]
            if now - req_time < self.time_window
        ]
        
        # Rate limit kontrolü
        if len(self.requests[ip_address]) >= self.max_requests:
            return False
        
        self.requests[ip_address].append(now)
        return True

# ====================== WEB HANDLER ======================
class WebHandler(BaseHTTPRequestHandler):
    """Web isteklerini işleyen sınıf"""
    bot = None  # Bot instance'ı buraya set edilecek
    
    def __init__(self, *args, **kwargs):
        # Rate limiter oluştur
        self.rate_limiter = RateLimiter(max_requests=30, time_window=60)
        super().__init__(*args, **kwargs)
    
    def _set_headers(self, content_type='text/html'):
        """Header'ları ayarla"""
        self.send_response(200)
        self.send_header('Content-type', f'{content_type}; charset=utf-8')
        self.send_header('Access-Control-Allow-Origin', '*')
        self.send_header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS')
        self.send_header('Access-Control-Allow-Headers', 'Content-Type')
        self.send_header('Cache-Control', 'no-cache, no-store, must-revalidate')
        self.send_header('Pragma', 'no-cache')
        self.send_header('Expires', '0')
        self.end_headers()
    
    def _check_ip_whitelist(self, ip_address: str, whitelist) -> bool:
        """IP whitelist kontrolü"""
        if not whitelist:
            return True
            
        for allowed_ip in whitelist:
            if '/' in allowed_ip:
                # CIDR notasyonu
                try:
                    network = ipaddress.ip_network(allowed_ip, strict=False)
                    if ipaddress.ip_address(ip_address) in network:
                        return True
                except:
                    continue
            elif ip_address == allowed_ip:
                return True
        
        return False
    
    def log_message(self, format, *args):
        """Log mesajlarını yazma"""
        pass
    
    def do_GET(self):
        """GET isteklerini işler"""
        client_ip = self.client_address[0]
        
        # Rate limiting kontrolü
        if not self.rate_limiter.is_allowed(client_ip):
            self.send_response(429)
            self.send_header('Content-type', 'text/html')
            self.end_headers()
            self.wfile.write(' Rate limit aşıldı. Lütfen 1 dakika bekleyin.'.encode('utf-8'))
            return
        
        # URL'yi parse et
        parsed_path = self.path.split('?')[0]
        query_string = self.path.split('?')[1] if '?' in self.path else ''
        
        bot = self.__class__.bot
        if not bot:
            self.send_response(503)
            self.send_header('Content-type', 'text/html')
            self.end_headers()
            self.wfile.write(' Bot başlatılmamış'.encode('utf-8'))
            return
            
        if bot.config['debug_mode']:
            print(f" GET {client_ip}: {self.path}")
        
        # Ana sayfa
        if parsed_path == '/':
            if query_string:
                self._handle_get_query(query_string)
            else:
                self._handle_main_page()
        
        # API endpoint'leri
        elif parsed_path == '/api/status':
            self._handle_api_status()
        
        elif parsed_path == '/api/channels':
            self._handle_api_channels()
        
        elif parsed_path == '/api/stats':
            self._handle_api_stats()
        
        elif parsed_path == '/api/oper_applications':
            self._handle_api_oper_applications()
        
        # 404
        else:
            self.send_response(404)
            self.send_header('Content-type', 'text/html')
            self.send_header('Access-Control-Allow-Origin', '*')
            self.end_headers()
            error_html = self._generate_error_page('404 - Sayfa Bulunamadı')
            self.wfile.write(error_html.encode('utf-8'))
    
    def _handle_get_query(self, query_string):
        """GET query string işle"""
        if '[Nick-Bilgi]' in query_string:
            response = """<div class="col-md-12 diz"><span> NS-HELP </span> <span class="pull-right"> <font color="red"><strong>Owner</strong></font> </span></div>
<div class="col-md-12 diz"><span> SADO </span> <span class="pull-right"> <font color="red"><strong>Admin</strong></font> </span></div>
<div class="col-md-12 diz"><span> KALPSIZ </span> <span class="pull-right"> <font color="red"><strong>Admin</strong></font> </span></div>
<div class="col-md-12 diz"><span> Q-CYCLE </span> <span class="pull-right"> <font color="red">Oper</font> </span></div>
<div class="col-md-12 diz"><span> CS-HELP </span> <span class="pull-right"> <font color="red">Oper</font> </span></div>
<div class="col-md-12 diz"><span> Q-WEB </span> <span class="pull-right"> <font color="red">Oper</font> </span></div>
<div class="col-md-12 diz"><span> HELP </span> <span class="pull-right"> <font color="red">Oper</font> </span></div>"""
            self._set_headers('text/html')
            self.wfile.write(response.encode('utf-8'))
        
        elif '[Kanal-Bilgi]' in query_string:
            response = """<div class="col-md-12 diz"><span> #help </span> <span class="pull-right"> 25 </span></div>
<div class="col-md-12 diz"><span> #admin </span> <span class="pull-right"> 8 </span></div>
<div class="col-md-12 diz"><span> #mavifm </span> <span class="pull-right"> 42 </span></div>
<div class="col-md-12 diz"><span> #opers </span> <span class="pull-right"> 5 </span></div>
<div class="col-md-12 diz"><span> #chat </span> <span class="pull-right"> 18 </span></div>
<div class="col-md-12 diz"><span> #music </span> <span class="pull-right"> 32 </span></div>
<div class="col-md-12 diz"><span> #support </span> <span class="pull-right"> 12 </span></div>"""
            self._set_headers('text/html')
            self.wfile.write(response.encode('utf-8'))
        
        elif '[Top10-Bilgi]' in query_string:
            response = """<div class="col-md-12 diz"><span> NS-HELP </span> <span class="pull-right"> 15,250 </span></div>
<div class="col-md-12 diz"><span> SADO </span> <span class="pull-right"> 12,800 </span></div>
<div class="col-md-12 diz"><span> KALPSIZ </span> <span class="pull-right"> 10,500 </span></div>
<div class="col-md-12 diz"><span> Q-CYCLE </span> <span class="pull-right"> 9,750 </span></div>
<div class="col-md-12 diz"><span> CS-HELP </span> <span class="pull-right"> 8,200 </span></div>
<div class="col-md-12 diz"><span> Q-WEB </span> <span class="pull-right"> 7,800 </span></div>
<div class="col-md-12 diz"><span> TUTKU </span> <span class="pull-right"> 6,500 </span></div>
<div class="col-md-12 diz"><span> MAVIFM </span> <span class="pull-right"> 5,200 </span></div>
<div class="col-md-12 diz"><span> RADYO </span> <span class="pull-right"> 4,800 </span></div>
<div class="col-md-12 diz"><span> DJ-SADO </span> <span class="pull-right"> 4,500 </span></div>"""
            self._set_headers('text/html')
            self.wfile.write(response.encode('utf-8'))
        
        elif '[Radyo-Bilgi]' in query_string:
            current_time = datetime.now().strftime("%H:%M")
            response = f"""<div class="col-md-12 radyo"><span> <i class="icon-user-1"></i>DJ :</span> <span class="dj"> SADO </span></div>
<div class="col-md-12 sarki"><span><i class="icon-music"></i>Calan Parca :</span> <span class="parca"> Tarkan - Simarik </span></div>
<div class="col-md-12 sarki"><span><i class="icon-headphones-3"></i>Dinleyen sayisi :</span> <span class="parca"> 125 </span></div>
<div class="col-md-12 radyo"><span> <i class="icon-star-empty-1"></i>Istek Sistemi :</span> <span class="djpanel"> ACIK </span></div>
<div class="col-md-12 radyo"><span> <i class="icon-clock"></i>Saat :</span> <span class="djpanel"> {current_time} </span></div>"""
            self._set_headers('text/html')
            self.wfile.write(response.encode('utf-8'))
        
        elif '[Armagan-Bilgi]' in query_string:
            response = """<div class="col-md-12 radyo"><span> <i class="icon-user-1"></i>DJ :</span> <span class="dj"> SADO </span></div>
<div class="col-md-12 sarki"><span><i class="icon-music"></i>Calan Parca :</span> <span class="parca"> Tarkan - Simarik </span></div>
<div class="col-md-12 sarki"><span><i class="icon-headphones-3"></i>Dinleyen sayisi :</span> <span class="parca"> 125 </span></div>
<div class="col-md-12 radyo"><span> <i class="icon-gift"></i>Armagan Sistemi :</span> <span class="djpanel"> ACIK </span></div>"""
            self._set_headers('text/html')
            self.wfile.write(response.encode('utf-8'))
        
        elif '[Yntc-list]' in query_string:
            response = """<div class="col-md-12 diz"><span> NS-HELP </span> <span class="pull-right"> <font color="red"><strong>Owner</strong></font> </span></div>
<div class="col-md-12 diz"><span> SADO </span> <span class="pull-right"> <font color="red"><strong>Admin</strong></font> </span></div>
<div class="col-md-12 diz"><span> KALPSIZ </span> <span class="pull-right"> <font color="red"><strong>Admin</strong></font> </span></div>
<div class="col-md-12 diz"><span> Q-CYCLE </span> <span class="pull-right"> <font color="red">Oper</font> </span></div>
<div class="col-md-12 diz"><span> CS-HELP </span> <span class="pull-right"> <font color="red">Oper</font> </span></div>
<div class="col-md-12 diz"><span> Q-WEB </span> <span class="pull-right"> <font color="red">Oper</font> </span></div>"""
            self._set_headers('text/html')
            self.wfile.write(response.encode('utf-8'))
        
        elif '[Ticket-List]' in query_string:
            bot = self.__class__.bot
            if not bot or not bot.tickets:
                response = "<div class='col-md-12'><p>Henuz ticket yok.</p></div>"
            else:
                response = ""
                for ticket_id, ticket in bot.tickets.items():
                    status_color = "green" if ticket.get('status') == 'closed' else "orange"
                    status_text = "KAPALI" if ticket.get('status') == 'closed' else "ACIK"
                    response += f"""<div class="col-md-12 diz">
                        <span> Ticket #{ticket_id} - {ticket.get('subject', 'Konu Yok')} </span>
                        <span class="pull-right">
                            <font color="{status_color}">{status_text}</font>
                        </span>
                    </div>"""
            self._set_headers('text/html')
            self.wfile.write(response.encode('utf-8'))
    
    def _handle_main_page(self):
        """Ana sayfayı işle"""
        bot = self.__class__.bot
        if not bot:
            self.send_response(503)
            self.send_header('Content-type', 'text/html')
            self.end_headers()
            self.wfile.write(' Bot başlatılmamış'.encode('utf-8'))
            return
        
        html = self._generate_main_page(bot)
        self._set_headers()
        self.wfile.write(html.encode('utf-8'))
    
    def _handle_api_status(self):
        """API status endpoint"""
        bot = self.__class__.bot
        if not bot:
            status = {
                'online': False,
                'error': 'Bot not initialized',
                'timestamp': datetime.now().isoformat()
            }
            self.send_response(200)
            self.send_header('Content-type', 'application/json')
            self.send_header('Access-Control-Allow-Origin', '*')
            self.end_headers()
            self.wfile.write(json.dumps(status, indent=2).encode('utf-8'))
            return
        
        status = {
            'online': bot.irc_socket is not None,
            'nick': bot.config['nickname'],
            'oper': bot.is_oper,
            'authenticated': bot.authenticated,
            'version': bot.config['version'],
            'uptime': bot.get_uptime(),
            'channels': len(bot.config['channels']),
            'tickets': len(bot.tickets),
            'oper_applications': len(bot.oper_applications),
            'timestamp': datetime.now().isoformat()
        }
        self.send_response(200)
        self.send_header('Content-type', 'application/json')
        self.send_header('Access-Control-Allow-Origin', '*')
        self.end_headers()
        self.wfile.write(json.dumps(status, indent=2).encode('utf-8'))
    
    def _handle_api_channels(self):
        """API channels endpoint"""
        bot = self.__class__.bot
        if not bot:
            self.send_response(200)
            self.send_header('Content-type', 'application/json')
            self.send_header('Access-Control-Allow-Origin', '*')
            self.end_headers()
            self.wfile.write(json.dumps({'channels': []}).encode('utf-8'))
            return
        
        channels = []
        for channel in bot.config['channels']:
            channels.append({
                'name': channel,
                'status': 'joined'
            })
        self.send_response(200)
        self.send_header('Content-type', 'application/json')
        self.send_header('Access-Control-Allow-Origin', '*')
        self.end_headers()
        self.wfile.write(json.dumps({'channels': channels}).encode('utf-8'))
    
    def _handle_api_stats(self):
        """API stats endpoint"""
        bot = self.__class__.bot
        if not bot:
            stats = {
                'uptime': '0',
                'start_time': datetime.now().isoformat(),
                'requests_served': 0,
                'tickets_count': 0,
                'points_count': 0,
                'oper_applications_count': 0,
                'memory_usage': 0
            }
            self.send_response(200)
            self.send_header('Content-type', 'application/json')
            self.send_header('Access-Control-Allow-Origin', '*')
            self.end_headers()
            self.wfile.write(json.dumps(stats).encode('utf-8'))
            return
        
        stats = {
            'uptime': bot.get_uptime(),
            'start_time': datetime.fromtimestamp(bot.start_time).isoformat(),
            'requests_served': len(bot.web_data.get('last_requests', {})),
            'tickets_count': len(bot.tickets),
            'points_count': len(bot.user_points),
            'oper_applications_count': len(bot.oper_applications),
            'memory_usage': self._get_memory_usage()
        }
        self.send_response(200)
        self.send_header('Content-type', 'application/json')
        self.send_header('Access-Control-Allow-Origin', '*')
        self.end_headers()
        self.wfile.write(json.dumps(stats).encode('utf-8'))
    
    def _handle_api_oper_applications(self):
        """API oper applications endpoint"""
        bot = self.__class__.bot
        if not bot:
            self.send_response(200)
            self.send_header('Content-type', 'application/json')
            self.send_header('Access-Control-Allow-Origin', '*')
            self.end_headers()
            self.wfile.write(json.dumps({'applications': []}).encode('utf-8'))
            return
        
        applications = []
        for app_id, app in bot.oper_applications.items():
            if app.get('status') == 'pending':
                applications.append({
                    'id': app_id,
                    'nick': app.get('nick'),
                    'name': app.get('name'),
                    'phone': app.get('phone'),
                    'applied_at': app.get('applied_at'),
                    'ip': app.get('ip')
                })
        self.send_response(200)
        self.send_header('Content-type', 'application/json')
        self.send_header('Access-Control-Allow-Origin', '*')
        self.end_headers()
        self.wfile.write(json.dumps({'applications': applications}).encode('utf-8'))
    
    def _get_memory_usage(self):
        """Bellek kullanımını al"""
        try:
            import psutil
            import os
            process = psutil.Process(os.getpid())
            return process.memory_info().rss / 1024 / 1024  # MB
        except:
            return 0
    
    def do_OPTIONS(self):
        """OPTIONS istekleri için CORS"""
        self.send_response(200)
        self.send_header('Access-Control-Allow-Origin', '*')
        self.send_header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS')
        self.send_header('Access-Control-Allow-Headers', 'Content-Type, Authorization')
        self.send_header('Access-Control-Max-Age', '86400')
        self.end_headers()
    
    def do_POST(self):
        """POST isteklerini işler"""
        client_ip = self.client_address[0]
        
        # Rate limiting kontrolü
        if not self.rate_limiter.is_allowed(client_ip):
            self.send_response(429)
            self.send_header('Content-type', 'text/html')
            self.end_headers()
            self.wfile.write(' Rate limit aşıldı. Lütfen 1 dakika bekleyin.'.encode('utf-8'))
            return
        
        content_length = int(self.headers.get('Content-Length', 0))
        post_data = self.rfile.read(content_length).decode('utf-8') if content_length > 0 else ''
        
        bot = self.__class__.bot
        if not bot:
            self.send_response(503)
            self.send_header('Content-type', 'text/html')
            self.end_headers()
            self.wfile.write('Bot başlatılmamış'.encode('utf-8'))
            return
        
        if bot.config['debug_mode']:
            print(f" POST {client_ip}: {self.path} | Data: {post_data[:200]}...")
        
        # POST verilerini parse et
        if post_data:
            try:
                # Logla
                if bot.config['log_requests']:
                    bot.log_action('WEB', f"POST {client_ip}: {post_data[:100]}")
                
                # Web panel formatına göre parse et
                delimiter = bot.config.get('web_delimiter', '¿')
                if delimiter in post_data:
                    self._handle_webpanel_post(bot, post_data, client_ip, delimiter)
                else:
                    # Normal form data
                    params = parse_qs(post_data)
                    if bot.config['debug_mode']:
                        print(f" Parsed Params: {params}")
                    
                    # API endpoint'leri
                    if self.path == '/api/send':
                        self._handle_api_send(bot, params, client_ip)
                    else:
                        self.send_response(400)
                        self.send_header('Content-type', 'text/html')
                        self.end_headers()
                        self.wfile.write(' Gecersiz POST formatı'.encode('utf-8'))
            except Exception as e:
                error_msg = f" POST parse hatası: {e}"
                print(error_msg)
                if bot.config['debug_mode']:
                    traceback.print_exc()
                
                self.send_response(400)
                self.send_header('Content-type', 'text/html')
                self.send_header('Access-Control-Allow-Origin', '*')
                self.end_headers()
                self.wfile.write(f' Hata: {str(e)}'.encode('utf-8'))
        else:
            self.send_response(400)
            self.send_header('Content-type', 'text/html')
            self.send_header('Access-Control-Allow-Origin', '*')
            self.end_headers()
            self.wfile.write(' POST verisi yok'.encode('utf-8'))
    
    def _handle_api_send(self, bot, params, client_ip):
        """API üzerinden komut gönder"""
        try:
            command = params.get('command', [''])[0]
            channel = params.get('channel', [bot.config['oper_channel']])[0]
            
            if not command:
                raise ValueError("Komut gerekli")
            
            # Güvenlik kontrolü
            whitelist = bot.config.get('ip_whitelist', [])
            if not self._check_ip_whitelist(client_ip, whitelist):
                self.send_response(403)
                self.send_header('Content-type', 'application/json')
                self.end_headers()
                self.wfile.write(json.dumps({'error': 'IP not allowed'}).encode('utf-8'))
                return
            
            # Komutu IRC'ye gönder
            if bot.irc_socket:
                bot.send_privmsg(channel, f"[WEB] {command}", color_type="info")
            
            self.send_response(200)
            self.send_header('Content-type', 'application/json')
            self.end_headers()
            self.wfile.write(json.dumps({'status': 'ok', 'command': command}).encode('utf-8'))
            
        except Exception as e:
            self.send_response(500)
            self.send_header('Content-type', 'application/json')
            self.end_headers()
            self.wfile.write(json.dumps({'error': str(e)}).encode('utf-8'))
    
    def _handle_webpanel_post(self, bot, data, client_ip, delimiter):
        """Web panel POST verilerini işler"""
        try:
            if '[Nick-kayit]' in data:
                self._handle_nick_kayit(bot, data, client_ip, delimiter)
            elif '[Radyo-istek]' in data:
                self._handle_radyo_istek(bot, data, client_ip, delimiter)
            elif '[Armagan-istek]' in data:
                self._handle_armagan_istek(bot, data, client_ip, delimiter)
            elif '[Xline-bildirim]' in data:
                self._handle_xline_bildirim(bot, data, client_ip, delimiter)
            elif '[Oper-Basvuru]' in data:
                self._handle_oper_basvuru(bot, data, client_ip, delimiter)
            elif '[Sikayet-bildirim]' in data:
                self._handle_sikayet_bildirim(bot, data, client_ip, delimiter)
            elif '[SpamFiltre-ekle]' in data:
                self._handle_spamfilter_ekle(bot, data, client_ip, delimiter)
            elif '[SpamFiltre-sil]' in data:
                self._handle_spamfilter_sil(bot, data, client_ip, delimiter)
            elif '[OS-SQLine-ekle]' in data:
                self._handle_os_sqline_ekle(bot, data, client_ip, delimiter)
            elif '[OS-SQLine-sil]' in data:
                self._handle_os_sqline_sil(bot, data, client_ip, delimiter)
            elif '[IP-Ban-ekle]' in data:
                self._handle_ip_ban_ekle(bot, data, client_ip, delimiter)
            elif '[Ticket-ekle]' in data:
                self._handle_ticket_ekle(bot, data, client_ip, delimiter)
            else:
                self.send_response(400)
                self.send_header('Content-type', 'text/html')
                self.send_header('Access-Control-Allow-Origin', '*')
                self.end_headers()
                self.wfile.write(' Bilinmeyen POST isteği'.encode('utf-8'))
        except Exception as e:
            error_msg = f" WebPanel POST hatası: {e}"
            print(error_msg)
            if bot.config['debug_mode']:
                traceback.print_exc()
            
            self.send_response(500)
            self.send_header('Content-type', 'text/html')
            self.send_header('Access-Control-Allow-Origin', '*')
            self.end_headers()
            self.wfile.write(f' Sunucu hatası: {str(e)}'.encode('utf-8'))
    
    def _handle_nick_kayit(self, bot, data, client_ip, delimiter):
        """Nick kayıt isteğini işler"""
        try:
            parts = data.split(delimiter)
            if len(parts) >= 5:
                nick = parts[1] if len(parts) > 1 else ''
                password = parts[2] if len(parts) > 2 else ''
                email = parts[3] if len(parts) > 3 else ''
                ip = parts[4] if len(parts) > 4 else client_ip
                
                print(f" Nick Kayıt: {nick}, Email: {email}, IP: {ip}")
                
                # Email validasyonu
                if not self._validate_email(email):
                    raise ValueError("Gecersiz email adresi")
                
                # IRC bağlantısı kontrolü
                irc_connected = bot.irc_socket is not None
                
                if irc_connected:
                    # NickServ'e kayıt komutu gönder
                    bot.send_raw(f"PRIVMSG NickServ :REGISTER {password} {email}")
                    bot.send_privmsg(bot.config['oper_channel'], 
                                   f" YENI NICK KAYDI: {nick} | Email: {email} | IP: {ip}", color_type="info")
                    bot.send_privmsg(bot.config['oper_channel'], 
                                   f" Komut: !nickkayit {nick} {password} sekilde onaylayabilirsiniz.", color_type="info")
                
                # Kayıt bilgilerini logla
                bot.log_action('WEB_NICK_KAYIT', f"{nick} | {email} | {ip}")
                
                if irc_connected:
                    response = """<div class="alert alert-success">
                        <h4> Kayıt Basarili!</h4>
                        <p>Nick kaydınız alındı. Yoneticiler onayladıktan sonra nickiniz aktif olacaktır.</p>
                        <p><strong>Nick:</strong> {nick}<br>
                        <strong>Email:</strong> {email}<br>
                        <strong>IP:</strong> {ip}</p>
                        <p class="small"><i> Yoneticiler IRC'de !nickkayit {nick} SIFRE komutu ile onaylayacaktır.</i></p>
                    </div>""".format(nick=nick, email=email, ip=ip)
                else:
                    response = """<div class="alert alert-warning">
                        <h4> Kayıt Alındı!</h4>
                        <p>Nick kaydınız alındı ancak IRC baglantısı olmadığı için hemen bildirilemedi.</p>
                        <p><strong>Nick:</strong> {nick}<br>
                        <strong>Email:</strong> {email}<br>
                        <strong>IP:</strong> {ip}</p>
                        <p class="small"><i> Bot IRC'ye baglandığında kaydınız bildirilecektir.</i></p>
                    </div>""".format(nick=nick, email=email, ip=ip)
                
                self._set_headers()
                self.wfile.write(response.encode('utf-8'))
            else:
                raise ValueError("Eksik parametre")
        except Exception as e:
            print(f" Nick kayıt hatası: {e}")
            self.send_response(500)
            self.send_header('Content-type', 'text/html')
            self.send_header('Access-Control-Allow-Origin', '*')
            self.end_headers()
            error_html = """<div class="alert alert-danger">
                <h4> Hata!</h4>
                <p>{error}</p>
            </div>""".format(error=str(e))
            self.wfile.write(error_html.encode('utf-8'))
    
    def _handle_radyo_istek(self, bot, data, client_ip, delimiter):
        """Radyo isteği işler"""
        try:
            parts = data.split(delimiter)
            if len(parts) >= 6:
                nick = parts[1] if len(parts) > 1 else ''
                artist = parts[2] if len(parts) > 2 else ''
                song = parts[3] if len(parts) > 3 else ''
                message = parts[4] if len(parts) > 4 else ''
                ip = parts[5] if len(parts) > 5 else client_ip
                
                print(f" Radyo Istek: {nick} - {artist} - {song}")
                
                # IRC bağlantısı kontrolü
                irc_connected = bot.irc_socket is not None
                
                if irc_connected:
                    # IRC'ye mesaj gönder - KANALA GÖNDER
                    bot.send_privmsg(bot.config['radio_channel'],
                                   f" WEB ISTEK ({nick}): {artist} - {song}", color_type="info")
                    if message:
                        bot.send_privmsg(bot.config['radio_channel'], f" Mesaj: {message}", color_type="info")
                
                # Logla
                bot.log_action('WEB_RADYO_ISTEK', f"{nick} | {artist} - {song} | {ip}")
                
                if irc_connected:
                    response = """<div class="alert alert-success">
                        <h4> Istek Gonderildi!</h4>
                        <p>Isteginiz DJ'lere iletildi.</p>
                        <p><strong>Nick:</strong> {nick}<br>
                        <strong>Sarkı:</strong> {artist} - {song}<br>
                        <strong>Mesaj:</strong> {message}</p>
                    </div>""".format(nick=nick, artist=artist, song=song, message=message or "Yok")
                else:
                    response = """<div class="alert alert-warning">
                        <h4> Istek Kaydedildi!</h4>
                        <p>Isteginiz kaydedildi ancak IRC baglantısı olmadığı için hemen iletilemedi.</p>
                        <p><strong>Nick:</strong> {nick}<br>
                        <strong>Sarkı:</strong> {artist} - {song}<br>
                        <strong>Mesaj:</strong> {message}</p>
                        <p class="small"><i> Bot IRC'ye baglandığında isteğiniz iletilecektir.</i></p>
                    </div>""".format(nick=nick, artist=artist, song=song, message=message or "Yok")
                
                self._set_headers()
                self.wfile.write(response.encode('utf-8'))
        except Exception as e:
            print(f" Radyo istek hatası: {e}")
            self.send_response(500)
            self.send_header('Content-type', 'text/html')
            self.send_header('Access-Control-Allow-Origin', '*')
            self.end_headers()
            error_html = f"""<div class="alert alert-danger">
                <h4> Hata!</h4>
                <p>{str(e)}</p>
            </div>"""
            self.wfile.write(error_html.encode('utf-8'))
    
    def _handle_armagan_istek(self, bot, data, client_ip, delimiter):
        """Armağan isteği işler"""
        try:
            parts = data.split(delimiter)
            if len(parts) >= 6:
                nick = parts[1] if len(parts) > 1 else ''
                sira = parts[2] if len(parts) > 2 else ''
                song = parts[3] if len(parts) > 3 else ''
                message = parts[4] if len(parts) > 4 else ''
                ip = parts[5] if len(parts) > 5 else client_ip
                
                print(f" Armagan Istek: {nick} - {message}")
                
                # IRC bağlantısı kontrolü
                irc_connected = bot.irc_socket is not None
                
                if irc_connected:
                    # IRC'ye mesaj gönder - KANALA GÖNDER
                    bot.send_privmsg(bot.config['radio_channel'],
                                   f" ARMAGAN ({nick}): {message}", color_type="info")
                    if song:
                        bot.send_privmsg(bot.config['radio_channel'], f" Sarkı: {song}", color_type="info")
                
                # Logla
                bot.log_action('WEB_ARMAGAN', f"{nick} | {message} | {ip}")
                
                if irc_connected:
                    response = """<div class="alert alert-success">
                        <h4> Armagan Gonderildi!</h4>
                        <p>Armagan isteginiz DJ'lere iletildi.</p>
                        <p><strong>Nick:</strong> {nick}<br>
                        <strong>Mesaj:</strong> {message}<br>
                        <strong>Sıra:</strong> {sira}</p>
                    </div>""".format(nick=nick, message=message, sira=sira or "Yok")
                else:
                    response = """<div class="alert alert-warning">
                        <h4> Armagan Kaydedildi!</h4>
                        <p>Armagan isteginiz kaydedildi ancak IRC baglantısı olmadığı için hemen iletilemedi.</p>
                        <p><strong>Nick:</strong> {nick}<br>
                        <strong>Mesaj:</strong> {message}<br>
                        <strong>Sıra:</strong> {sira}</p>
                        <p class="small"><i> Bot IRC'ye baglandığında armaganınız iletilecektir.</i></p>
                    </div>""".format(nick=nick, message=message, sira=sira or "Yok")
                
                self._set_headers()
                self.wfile.write(response.encode('utf-8'))
        except Exception as e:
            print(f" Armagan hatası: {e}")
            self.send_response(500)
            self.send_header('Content-type', 'text/html')
            self.send_header('Access-Control-Allow-Origin', '*')
            self.end_headers()
            error_html = f"""<div class="alert alert-danger">
                <h4> Hata!</h4>
                <p>{str(e)}</p>
            </div>"""
            self.wfile.write(error_html.encode('utf-8'))
    
    def _handle_xline_bildirim(self, bot, data, client_ip, delimiter):
        """XLine bildirimi işler - KANALA GÖNDERİR"""
        try:
            parts = data.split(delimiter)
            if len(parts) >= 4:
                nick = parts[1] if len(parts) > 1 else ''
                message = parts[2] if len(parts) > 2 else ''
                ip = parts[3] if len(parts) > 3 else client_ip
                
                print(f" XLine Bildirim: {nick} - {message}")
                
                # IRC bağlantısı kontrolü
                irc_connected = bot.irc_socket is not None
                
                if irc_connected:
                    # ⚡ DEĞİŞİKLİK: Özele değil, kanala gönder
                    # Oper kanalına bildir (herkes görsün)
                    bot.send_privmsg(bot.config['oper_channel'], 
                                   f" X:LINE BILDIRIM: {nick} | IP: {ip}", color_type="warning")
                    bot.send_privmsg(bot.config['oper_channel'], 
                                   f" Mesaj: {message}", color_type="info")
                
                # Logla
                bot.log_action('WEB_XLINE', f"{nick} | {message} | {ip}")
                
                if irc_connected:
                    response = """<div class="alert alert-warning">
                        <h4> Bildirim Gonderildi!</h4>
                        <p>X:Line bildiriminiz kanala iletildi.</p>
                        <p><strong>Sikayet Edilen:</strong> {nick}<br>
                        <strong>Sebep:</strong> {message}<br>
                        <strong>Bildiren IP:</strong> {ip}</p>
                        <p class="small"><i> Mesaj #{oper_channel} kanalına gonderildi.</i></p>
                    </div>""".format(nick=nick, message=message, ip=ip, oper_channel=bot.config['oper_channel'])
                else:
                    response = """<div class="alert alert-warning">
                        <h4> Bildirim Kaydedildi!</h4>
                        <p>X:Line bildiriminiz kaydedildi ancak IRC baglantısı olmadığı için hemen iletilemedi.</p>
                        <p><strong>Sikayet Edilen:</strong> {nick}<br>
                        <strong>Sebep:</strong> {message}<br>
                        <strong>Bildiren IP:</strong> {ip}</p>
                        <p class="small"><i> Bot IRC'ye baglandığında bildiriminiz iletilecektir.</i></p>
                    </div>""".format(nick=nick, message=message, ip=ip)
                
                self._set_headers()
                self.wfile.write(response.encode('utf-8'))
        except Exception as e:
            print(f" XLine bildirim hatası: {e}")
            self.send_response(500)
            self.send_header('Content-type', 'text/html')
            self.send_header('Access-Control-Allow-Origin', '*')
            self.end_headers()
            error_html = f"""<div class="alert alert-danger">
                <h4> Hata!</h4>
                <p>{str(e)}</p>
            </div>"""
            self.wfile.write(error_html.encode('utf-8'))
    
    def _handle_oper_basvuru(self, bot, data, client_ip, delimiter):
        """Oper başvurusu işler"""
        try:
            parts = data.split(delimiter)
            if len(parts) >= 11:
                isim = parts[1] if len(parts) > 1 else ''
                nick = parts[2] if len(parts) > 2 else ''
                tel = parts[3] if len(parts) > 3 else ''
                skype = parts[4] if len(parts) > 4 else ''
                dogum = parts[5] if len(parts) > 5 else ''
                online = parts[6] if len(parts) > 6 else ''
                ilgi = parts[7] if len(parts) > 7 else ''
                ref = parts[8] if len(parts) > 8 else ''
                hak = parts[9] if len(parts) > 9 else ''
                ip = parts[10] if len(parts) > 10 else client_ip
                
                print(f" Oper Basvuru: {nick} ({isim})")
                
                # Başvuru yasak kontrolü
                if nick in bot.oper_application_bans:
                    ban_info = bot.oper_application_bans[nick]
                    response = f"""<div class="alert alert-danger">
                        <h4> Basvurunuz Reddedildi!</h4>
                        <p>Bu nick için basvuru yapma yasağı bulunuyor.</p>
                        <p><strong>Yasaklanma Sebep:</strong> {ban_info.get('reason', 'Belirtilmemiş')}<br>
                        <strong>Yasaklanma Tarihi:</strong> {ban_info.get('banned_at', 'Bilinmiyor')}<br>
                        <strong>Yasaklayan:</strong> {ban_info.get('banned_by', 'Bilinmiyor')}</p>
                    </div>"""
                    self._set_headers()
                    self.wfile.write(response.encode('utf-8'))
                    return
                
                # Başvuru ID'si oluştur
                app_id = bot.generate_application_id()
                
                # Başvuruyu kaydet
                bot.oper_applications[app_id] = {
                    'id': app_id,
                    'name': isim,
                    'nick': nick,
                    'phone': tel,
                    'skype': skype,
                    'birth_date': dogum,
                    'online_hours': online,
                    'interest': ilgi,
                    'reference': ref,
                    'about': hak,
                    'ip': ip,
                    'applied_at': datetime.now().isoformat(),
                    'status': 'pending',
                    'approved_by': None,
                    'approved_at': None,
                    'rejected_reason': None
                }
                
                # IRC bağlantısı kontrolü
                irc_connected = bot.irc_socket is not None
                
                if irc_connected:
                    # Adminlere bildirim - KANALA GÖNDER
                    bot.send_privmsg(bot.config['oper_channel'], 
                                   f" YENI OPER BASVURUSU #{app_id}", color_type="info")
                    bot.send_privmsg(bot.config['oper_channel'], 
                                   f" {nick} ({isim}) basvurdu", color_type="info")
                    bot.send_privmsg(bot.config['oper_channel'], 
                                   f" Tel: {tel} | Skype: {skype}", color_type="info")
                    bot.send_privmsg(bot.config['oper_channel'], 
                                   f" Online: {online} | Ilgi: {ilgi}", color_type="info")
                    bot.send_privmsg(bot.config['oper_channel'], 
                                   f" IP: {ip}", color_type="info")
                    bot.send_privmsg(bot.config['oper_channel'], 
                                   f" Onay için: !onaylandi {nick} veya !reddedildi {nick} sebep", color_type="info")
                    bot.send_privmsg(bot.config['oper_channel'], 
                                   f" Yasak için: !basvuruyasak {nick} sebep", color_type="info")
                
                # Logla
                bot.log_action('WEB_OPER_BASVURU', f"{nick} ({isim}) | ID: {app_id}")
                
                if irc_connected:
                    response = """<div class="alert alert-info">
                        <h4> Basvuru Alındı!</h4>
                        <p>Oper basvurunuz alındı. Basvuru ID: #{app_id}</p>
                        <p>Yoneticiler basvurunuzu inceleyecek ve size ozel mesaj yoluyla donus yapacaktır.</p>
                        <p><strong>İsim:</strong> {isim}<br>
                        <strong>Nick:</strong> {nick}<br>
                        <strong>Online Saat:</strong> {online}<br>
                        <strong>İlgi Alanı:</strong> {ilgi}</p>
                        <p class="small"><i> Basvuru durumunu takip etmek için IRC'de bulunmanız onerilir.</i></p>
                    </div>""".format(isim=isim, nick=nick, online=online, ilgi=ilgi, app_id=app_id)
                else:
                    response = """<div class="alert alert-info">
                        <h4> Basvuru Alındı!</h4>
                        <p>Oper basvurunuz alındı. Basvuru ID: #{app_id}</p>
                        <p><strong>UYARI:</strong> IRC baglantısı olmadığı için bildirim yapılamadı.</p>
                        <p><strong>İsim:</strong> {isim}<br>
                        <strong>Nick:</strong> {nick}<br>
                        <strong>Online Saat:</strong> {online}<br>
                        <strong>İlgi Alanı:</strong> {ilgi}</p>
                        <p class="small"><i> Bot IRC'ye baglandığında basvurunuz yoneticilere iletilecektir.</i></p>
                    </div>""".format(isim=isim, nick=nick, online=online, ilgi=ilgi, app_id=app_id)
                
                self._set_headers()
                self.wfile.write(response.encode('utf-8'))
        except Exception as e:
            print(f" Oper basvuru hatası: {e}")
            self.send_response(500)
            self.send_header('Content-type', 'text/html')
            self.send_header('Access-Control-Allow-Origin', '*')
            self.end_headers()
            error_html = f"""<div class="alert alert-danger">
                <h4> Hata!</h4>
                <p>{str(e)}</p>
            </div>"""
            self.wfile.write(error_html.encode('utf-8'))
    
    def _handle_sikayet_bildirim(self, bot, data, client_ip, delimiter):
        """Şikayet bildirimi işler - KANALA GÖNDERİR"""
        try:
            parts = data.split(delimiter)
            if len(parts) >= 4:
                nick = parts[1] if len(parts) > 1 else ''
                message = parts[2] if len(parts) > 2 else ''
                ip = parts[3] if len(parts) > 3 else client_ip
                
                print(f" Sikayet Bildirim: {nick} - {message}")
                
                # IRC bağlantısı kontrolü
                irc_connected = bot.irc_socket is not None
                
                if irc_connected:
                    # ⚡ DEĞİŞİKLİK: Özele değil, kanala gönder
                    # Oper kanalına bildir (herkes görsün)
                    bot.send_privmsg(bot.config['oper_channel'], 
                                   f" SIKAYET BILDIRIMI: {nick}", color_type="warning")
                    bot.send_privmsg(bot.config['oper_channel'], 
                                   f" Sikayet: {message}", color_type="info")
                    bot.send_privmsg(bot.config['oper_channel'], 
                                   f" IP: {ip}", color_type="info")
                
                # Logla
                bot.log_action('WEB_SIKAYET', f"{nick} | {message} | {ip}")
                
                if irc_connected:
                    response = """<div class="alert alert-warning">
                        <h4> Sikayet Kaydedildi!</h4>
                        <p>Sikayetiniz kanala iletildi. Tesekkur ederiz.</p>
                        <p><strong>Sikayet Edilen:</strong> {nick}<br>
                        <strong>Sebep:</strong> {message}<br>
                        <strong>Bildiren IP:</strong> {ip}</p>
                        <p class="small"><i> Mesaj #{oper_channel} kanalına gonderildi.</i></p>
                    </div>""".format(nick=nick, message=message, ip=ip, oper_channel=bot.config['oper_channel'])
                else:
                    response = """<div class="alert alert-warning">
                        <h4> Sikayet Kaydedildi!</h4>
                        <p>Sikayetiniz kaydedildi ancak IRC baglantısı olmadığı için hemen iletilemedi.</p>
                        <p><strong>Sikayet Edilen:</strong> {nick}<br>
                        <strong>Sebep:</strong> {message}<br>
                        <strong>Bildiren IP:</strong> {ip}</p>
                        <p class="small"><i> Bot IRC'ye baglandığında sikayetiniz iletilecektir.</i></p>
                    </div>""".format(nick=nick, message=message, ip=ip)
                
                self._set_headers()
                self.wfile.write(response.encode('utf-8'))
        except Exception as e:
            print(f" Sikayet hatası: {e}")
            self.send_response(500)
            self.send_header('Content-type', 'text/html')
            self.send_header('Access-Control-Allow-Origin', '*')
            self.end_headers()
            error_html = f"""<div class="alert alert-danger">
                <h4> Hata!</h4>
                <p>{str(e)}</p>
            </div>"""
            self.wfile.write(error_html.encode('utf-8'))
    
    def _handle_spamfilter_ekle(self, bot, data, client_ip, delimiter):
        """Spamfilter ekleme işler"""
        try:
            parts = data.split(delimiter)
            if len(parts) >= 6:
                nick = parts[1] if len(parts) > 1 else ''
                tur = parts[2] if len(parts) > 2 else ''
                aksiyon = parts[3] if len(parts) > 3 else ''
                filtre = parts[4] if len(parts) > 4 else ''
                ip = parts[5] if len(parts) > 5 else client_ip
                
                print(f" SpamFilter Ekle: {nick} - {tur} - {filtre}")
                
                # Admin kontrolü
                admin_nicks = bot.config.get('admin_nicks', [])
                if nick.upper() not in [n.upper() for n in admin_nicks]:
                    self.send_response(403)
                    self.send_header('Content-type', 'text/html')
                    self.send_header('Access-Control-Allow-Origin', '*')
                    self.end_headers()
                    error_html = """<div class="alert alert-danger">
                        <h4> Yetkisiz!</h4>
                        <p>Bu işlem için admin yetkisi gerekiyor.</p>
                    </div>"""
                    self.wfile.write(error_html.encode('utf-8'))
                    return
                
                # IRC bağlantısı kontrolü
                irc_connected = bot.irc_socket is not None
                
                if not irc_connected:
                    self.send_response(500)
                    self.send_header('Content-type', 'text/html')
                    self.send_header('Access-Control-Allow-Origin', '*')
                    self.end_headers()
                    error_html = """<div class="alert alert-danger">
                        <h4> Hata!</h4>
                        <p>IRC baglantısı yok. SpamFilter eklenemiyor.</p>
                    </div>"""
                    self.wfile.write(error_html.encode('utf-8'))
                    return
                
                # Spamfilter komutu gönder
                if tur == 'normal':
                    bot.send_raw(f"SPAMFILTER add cpnN block - :GuvenLik: *{filtre}*")
                elif tur == 'nick':
                    bot.send_raw(f"SPAMFILTER add u block - :GuvenLik: ^({filtre}!.+@.+:.+)$")
                elif tur == 'ident':
                    bot.send_raw(f"SPAMFILTER add u block - :GuvenLik: ^(.+!{filtre}@.+:.+)$")
                elif tur == 'ip':
                    bot.send_raw(f"SPAMFILTER add u gzline - Yasak_IP : ^(.+!.+@{filtre}:.+)$")
                
                # Adminlere bildir - KANALA GÖNDER
                bot.send_privmsg(bot.config['oper_channel'], f" SPAMFILTER EKLENDI: {nick}", color_type="info")
                bot.send_privmsg(bot.config['oper_channel'], f" Tur: {tur} | Filtre: {filtre}", color_type="info")
                
                # Logla
                bot.log_action('WEB_SPAMFILTER_EKLE', f"{nick} | {tur}:{filtre}")
                
                response = """<div class="alert alert-success">
                    <h4> SpamFilter Eklendi!</h4>
                    <p>Spam filtreniz basarıyla eklendi.</p>
                    <p><strong>Tur:</strong> {tur}<br>
                    <strong>Filtre:</strong> {filtre}<br>
                    <strong>Aksiyon:</strong> {aksiyon}</p>
                </div>""".format(tur=tur, filtre=filtre, aksiyon=aksiyon)
                self._set_headers()
                self.wfile.write(response.encode('utf-8'))
        except Exception as e:
            print(f" SpamFilter ekleme hatası: {e}")
            self.send_response(500)
            self.send_header('Content-type', 'text/html')
            self.send_header('Access-Control-Allow-Origin', '*')
            self.end_headers()
            error_html = f"""<div class="alert alert-danger">
                <h4> Hata!</h4>
                <p>{str(e)}</p>
            </div>"""
            self.wfile.write(error_html.encode('utf-8'))
    
    def _handle_spamfilter_sil(self, bot, data, client_ip, delimiter):
        """Spamfilter silme işler"""
        try:
            parts = data.split(delimiter)
            if len(parts) >= 6:
                nick = parts[1] if len(parts) > 1 else ''
                tur = parts[2] if len(parts) > 2 else ''
                aksiyon = parts[3] if len(parts) > 3 else ''
                filtre = parts[4] if len(parts) > 4 else ''
                ip = parts[5] if len(parts) > 5 else client_ip
                
                print(f" SpamFilter Sil: {nick} - {tur} - {filtre}")
                
                # Admin kontrolü
                admin_nicks = bot.config.get('admin_nicks', [])
                if nick.upper() not in [n.upper() for n in admin_nicks]:
                    self.send_response(403)
                    self.send_header('Content-type', 'text/html')
                    self.send_header('Access-Control-Allow-Origin', '*')
                    self.end_headers()
                    error_html = """<div class="alert alert-danger">
                        <h4> Yetkisiz!</h4>
                        <p>Bu işlem için admin yetkisi gerekiyor.</p>
                    </div>"""
                    self.wfile.write(error_html.encode('utf-8'))
                    return
                
                # IRC bağlantısı kontrolü
                irc_connected = bot.irc_socket is not None
                
                if not irc_connected:
                    self.send_response(500)
                    self.send_header('Content-type', 'text/html')
                    self.send_header('Access-Control-Allow-Origin', '*')
                    self.end_headers()
                    error_html = """<div class="alert alert-danger">
                        <h4> Hata!</h4>
                        <p>IRC baglantısı yok. SpamFilter silinemiyor.</p>
                    </div>"""
                    self.wfile.write(error_html.encode('utf-8'))
                    return
                
                # Spamfilter silme komutu gönder
                if tur == 'normal':
                    bot.send_raw(f"SPAMFILTER del cpnN block - :GuvenLik: *{filtre}*")
                elif tur == 'nick':
                    bot.send_raw(f"SPAMFILTER del u block - :GuvenLik: ^({filtre}!.+@.+:.+)$")
                elif tur == 'ident':
                    bot.send_raw(f"SPAMFILTER del u block - :GuvenLik: ^(.+!{filtre}@.+:.+)$")
                elif tur == 'ip':
                    bot.send_raw(f"SPAMFILTER del u gzline - Yasak_IP : ^(.+!.+@{filtre}:.+)$")
                
                # Adminlere bildir - KANALA GÖNDER
                bot.send_privmsg(bot.config['oper_channel'], f" SPAMFILTER SILINDI: {nick}", color_type="info")
                bot.send_privmsg(bot.config['oper_channel'], f" Tur: {tur} | Filtre: {filtre}", color_type="info")
                
                # Logla
                bot.log_action('WEB_SPAMFILTER_SIL', f"{nick} | {tur}:{filtre}")
                
                response = """<div class="alert alert-success">
                    <h4> SpamFilter Silindi!</h4>
                    <p>Spam filtreniz basarıyla silindi.</p>
                    <p><strong>Tur:</strong> {tur}<br>
                    <strong>Filtre:</strong> {filtre}<br>
                    <strong>Aksiyon:</strong> {aksiyon}</p>
                </div>""".format(tur=tur, filtre=filtre, aksiyon=aksiyon)
                self._set_headers()
                self.wfile.write(response.encode('utf-8'))
        except Exception as e:
            print(f" SpamFilter silme hatası: {e}")
            self.send_response(500)
            self.send_header('Content-type', 'text/html')
            self.send_header('Access-Control-Allow-Origin', '*')
            self.end_headers()
            error_html = f"""<div class="alert alert-danger">
                <h4> Hata!</h4>
                <p>{str(e)}</p>
            </div>"""
            self.wfile.write(error_html.encode('utf-8'))
    
    def _handle_os_sqline_ekle(self, bot, data, client_ip, delimiter):
        """OS SQLine ekleme işler"""
        try:
            parts = data.split(delimiter)
            if len(parts) >= 6:
                nick = parts[1] if len(parts) > 1 else ''
                hedef = parts[2] if len(parts) > 2 else ''
                sure = parts[3] if len(parts) > 3 else ''
                sebep = parts[4] if len(parts) > 4 else ''
                ip = parts[5] if len(parts) > 5 else client_ip
                
                print(f" OS SQLine Ekle: {nick} - {hedef} - {sure}gun")
                
                # Admin kontrolü
                admin_nicks = bot.config.get('admin_nicks', [])
                if nick.upper() not in [n.upper() for n in admin_nicks]:
                    self.send_response(403)
                    self.send_header('Content-type', 'text/html')
                    self.send_header('Access-Control-Allow-Origin', '*')
                    self.end_headers()
                    error_html = """<div class="alert alert-danger">
                        <h4> Yetkisiz!</h4>
                        <p>Bu işlem için admin yetkisi gerekiyor.</p>
                    </div>"""
                    self.wfile.write(error_html.encode('utf-8'))
                    return
                
                # IRC bağlantısı kontrolü
                irc_connected = bot.irc_socket is not None
                
                if not irc_connected:
                    self.send_response(500)
                    self.send_header('Content-type', 'text/html')
                    self.send_header('Access-Control-Allow-Origin', '*')
                    self.end_headers()
                    error_html = """<div class="alert alert-danger">
                        <h4> Hata!</h4>
                        <p>IRC baglantısı yok. OS SQLine eklenemiyor.</p>
                    </div>"""
                    self.wfile.write(error_html.encode('utf-8'))
                    return
                
                # OS SQLine komutu gönder
                if sure == '0':
                    bot.send_raw(f"OS SQLINE +0 {hedef} :{sebep} (WebPanel:{nick})")
                else:
                    bot.send_raw(f"OS SQLINE +{sure} {hedef} :{sebep} (WebPanel:{nick})")
                
                # Adminlere bildir - KANALA GÖNDER
                bot.send_privmsg(bot.config['oper_channel'], f" OS SQLINE EKLENDI: {nick}", color_type="info")
                bot.send_privmsg(bot.config['oper_channel'], f" Hedef: {hedef} | Sure: {sure}gun", color_type="info")
                bot.send_privmsg(bot.config['oper_channel'], f" Sebep: {sebep}", color_type="info")
                
                # Logla
                bot.log_action('WEB_OS_SQLINE_EKLE', f"{nick} | {hedef} | {sure}gun | {sebep}")
                
                response = """<div class="alert alert-success">
                    <h4> OS SQLine Eklendi!</h4>
                    <p>OS SQLine basarıyla eklendi.</p>
                    <p><strong>Hedef:</strong> {hedef}<br>
                    <strong>Sure:</strong> {sure} gun<br>
                    <strong>Sebep:</strong> {sebep}</p>
                </div>""".format(hedef=hedef, sure=sure, sebep=sebep)
                self._set_headers()
                self.wfile.write(response.encode('utf-8'))
        except Exception as e:
            print(f" OS SQLine ekleme hatası: {e}")
            self.send_response(500)
            self.send_header('Content-type', 'text/html')
            self.send_header('Access-Control-Allow-Origin', '*')
            self.end_headers()
            error_html = f"""<div class="alert alert-danger">
                <h4> Hata!</h4>
                <p>{str(e)}</p>
            </div>"""
            self.wfile.write(error_html.encode('utf-8'))
    
    def _handle_os_sqline_sil(self, bot, data, client_ip, delimiter):
        """OS SQLine silme işler"""
        try:
            parts = data.split(delimiter)
            if len(parts) >= 4:
                nick = parts[1] if len(parts) > 1 else ''
                hedef = parts[2] if len(parts) > 2 else ''
                ip = parts[3] if len(parts) > 3 else client_ip
                
                print(f" OS SQLine Sil: {nick} - {hedef}")
                
                # Admin kontrolü
                admin_nicks = bot.config.get('admin_nicks', [])
                if nick.upper() not in [n.upper() for n in admin_nicks]:
                    self.send_response(403)
                    self.send_header('Content-type', 'text/html')
                    self.send_header('Access-Control-Allow-Origin', '*')
                    self.end_headers()
                    error_html = """<div class="alert alert-danger">
                        <h4> Yetkisiz!</h4>
                        <p>Bu işlem için admin yetkisi gerekiyor.</p>
                    </div>"""
                    self.wfile.write(error_html.encode('utf-8'))
                    return
                
                # IRC bağlantısı kontrolü
                irc_connected = bot.irc_socket is not None
                
                if not irc_connected:
                    self.send_response(500)
                    self.send_header('Content-type', 'text/html')
                    self.send_header('Access-Control-Allow-Origin', '*')
                    self.end_headers()
                    error_html = """<div class="alert alert-danger">
                        <h4> Hata!</h4>
                        <p>IRC baglantısı yok. OS SQLine silinemiyor.</p>
                    </div>"""
                    self.wfile.write(error_html.encode('utf-8'))
                    return
                
                # OS SQLine silme komutu gönder
                bot.send_raw(f"OS SQLINE - {hedef}")
                
                # Adminlere bildir - KANALA GÖNDER
                bot.send_privmsg(bot.config['oper_channel'], f" OS SQLINE SILINDI: {nick}", color_type="info")
                bot.send_privmsg(bot.config['oper_channel'], f" Hedef: {hedef}", color_type="info")
                
                # Logla
                bot.log_action('WEB_OS_SQLINE_SIL', f"{nick} | {hedef}")
                
                response = """<div class="alert alert-success">
                    <h4> OS SQLine Silindi!</h4>
                    <p>OS SQLine basarıyla silindi.</p>
                    <p><strong>Hedef:</strong> {hedef}</p>
                </div>""".format(hedef=hedef)
                self._set_headers()
                self.wfile.write(response.encode('utf-8'))
        except Exception as e:
            print(f" OS SQLine silme hatası: {e}")
            self.send_response(500)
            self.send_header('Content-type', 'text/html')
            self.send_header('Access-Control-Allow-Origin', '*')
            self.end_headers()
            error_html = f"""<div class="alert alert-danger">
                <h4> Hata!</h4>
                <p>{str(e)}</p>
            </div>"""
            self.wfile.write(error_html.encode('utf-8'))
    
    def _handle_ip_ban_ekle(self, bot, data, client_ip, delimiter):
        """IP Ban ekleme işler"""
        try:
            parts = data.split(delimiter)
            if len(parts) >= 6:
                nick = parts[1] if len(parts) > 1 else ''
                ip_addr = parts[2] if len(parts) > 2 else ''
                sure = parts[3] if len(parts) > 3 else ''
                sebep = parts[4] if len(parts) > 4 else ''
                istek_ip = parts[5] if len(parts) > 5 else client_ip
                
                print(f" IP Ban Ekle: {nick} - {ip_addr} - {sure}gun")
                
                # Admin kontrolü
                admin_nicks = bot.config.get('admin_nicks', [])
                if nick.upper() not in [n.upper() for n in admin_nicks]:
                    self.send_response(403)
                    self.send_header('Content-type', 'text/html')
                    self.send_header('Access-Control-Allow-Origin', '*')
                    self.end_headers()
                    error_html = """<div class="alert alert-danger">
                        <h4> Yetkisiz!</h4>
                        <p>Bu işlem için admin yetkisi gerekiyor.</p>
                    </div>"""
                    self.wfile.write(error_html.encode('utf-8'))
                    return
                
                # IP validasyonu
                if not self._validate_ip(ip_addr):
                    self.send_response(400)
                    self.send_header('Content-type', 'text/html')
                    self.send_header('Access-Control-Allow-Origin', '*')
                    self.end_headers()
                    error_html = """<div class="alert alert-danger">
                        <h4> Hata!</h4>
                        <p>Geçersiz IP adresi.</p>
                    </div>"""
                    self.wfile.write(error_html.encode('utf-8'))
                    return
                
                # IRC bağlantısı kontrolü
                irc_connected = bot.irc_socket is not None
                
                if not irc_connected:
                    self.send_response(500)
                    self.send_header('Content-type', 'text/html')
                    self.send_header('Access-Control-Allow-Origin', '*')
                    self.end_headers()
                    error_html = """<div class="alert alert-danger">
                        <h4> Hata!</h4>
                        <p>IRC baglantısı yok. IP Ban eklenemiyor.</p>
                    </div>"""
                    self.wfile.write(error_html.encode('utf-8'))
                    return
                
                # IP Ban komutu gönder
                if sure == '0':
                    bot.send_raw(f"GLINE *@{ip_addr} :{sebep} (WebPanel:{nick})")
                else:
                    minutes = int(sure) * 1440
                    bot.send_raw(f"GLINE *@{ip_addr} {minutes} :{sebep} (WebPanel:{nick})")
                
                # Adminlere bildir - KANALA GÖNDER
                bot.send_privmsg(bot.config['oper_channel'], f" IP BAN EKLENDI: {nick}", color_type="info")
                bot.send_privmsg(bot.config['oper_channel'], f" IP: {ip_addr} | Sure: {sure}gun", color_type="info")
                bot.send_privmsg(bot.config['oper_channel'], f" Sebep: {sebep}", color_type="info")
                
                # Logla
                bot.log_action('WEB_IP_BAN_EKLE', f"{nick} | {ip_addr} | {sure}gun | {sebep}")
                
                response = """<div class="alert alert-success">
                    <h4> IP Ban Eklendi!</h4>
                    <p>IP Ban başarıyla eklendi.</p>
                    <p><strong>IP:</strong> {ip_addr}<br>
                    <strong>Süre:</strong> {sure} gün<br>
                    <strong>Sebep:</strong> {sebep}</p>
                </div>""".format(ip_addr=ip_addr, sure=sure, sebep=sebep)
                self._set_headers()
                self.wfile.write(response.encode('utf-8'))
        except Exception as e:
            print(f" IP Ban ekleme hatası: {e}")
            self.send_response(500)
            self.send_header('Content-type', 'text/html')
            self.send_header('Access-Control-Allow-Origin', '*')
            self.end_headers()
            error_html = f"""<div class="alert alert-danger">
                <h4> Hata!</h4>
                <p>{str(e)}</p>
            </div>"""
            self.wfile.write(error_html.encode('utf-8'))
    
    def _handle_ticket_ekle(self, bot, data, client_ip, delimiter):
        """Ticket ekleme işler - SADECE KANALA GÖNDER"""
        try:
            parts = data.split(delimiter)
            if len(parts) >= 5:
                nick = parts[1] if len(parts) > 1 else ''
                konu = parts[2] if len(parts) > 2 else ''
                mesaj = parts[3] if len(parts) > 3 else ''
                ip = parts[4] if len(parts) > 4 else client_ip
                
                print(f" Ticket Ekle: {nick} - {konu}")
                
                # Ticket oluştur
                ticket_id = bot.next_ticket_id
                bot.tickets[ticket_id] = {
                    'id': ticket_id,
                    'nick': nick,
                    'subject': konu,
                    'message': mesaj,
                    'ip': ip,
                    'status': 'open',
                    'created': datetime.now().isoformat(),
                    'updated': datetime.now().isoformat()
                }
                bot.next_ticket_id += 1
                
                # ⚡ DEĞİŞİKLİK: SADECE OPER KANALINA GÖNDER
                if bot.irc_socket:
                    oper_channel = bot.config['oper_channel']
                    
                    # Türkçe karakterleri düzelt ve IRC uyumlu hale getir
                    safe_nick = bot._replace_turkish_chars(nick)
                    safe_konu = bot._replace_turkish_chars(konu)
                    safe_mesaj = bot._replace_turkish_chars(mesaj)
                    
                    # Renkli başlık mesajı
                    title_msg = IRCColors.colorize(f"🎫 YENI TICKET #{ticket_id}", "07") + " " + IRCColors.colorize(f"Konu: {safe_konu}", "12")
                    bot.send_raw(f"PRIVMSG {oper_channel} :{title_msg}")
                    
                    # Gönderen bilgisi
                    sender_msg = IRCColors.colorize("Gönderen:", "03") + " " + IRCColors.colorize(f"{safe_nick}", "15") + " " + IRCColors.colorize("| IP:", "03") + " " + IRCColors.colorize(f"{ip}", "15")
                    bot.send_raw(f"PRIVMSG {oper_channel} :{sender_msg}")
                    
                    # Mesaj (varsa)
                    if safe_mesaj:
                        mesaj_preview = safe_mesaj[:150] + ('...' if len(safe_mesaj) > 150 else '')
                        mesaj_msg = IRCColors.colorize("Mesaj:", "03") + " " + IRCColors.colorize(f"{mesaj_preview}", "15")
                        bot.send_raw(f"PRIVMSG {oper_channel} :{mesaj_msg}")
                    
                    # Yönetim komutları
                    management_msg = IRCColors.colorize("Yönetim:", "04") + " " + IRCColors.colorize(f"!ticket view {ticket_id}", "08") + " " + IRCColors.colorize("|", "14") + " " + IRCColors.colorize(f"!ticket close {ticket_id}", "08")
                    bot.send_raw(f"PRIVMSG {oper_channel} :{management_msg}")
                
                # Logla
                bot.log_action('WEB_TICKET_EKLE', f"{nick} | Ticket#{ticket_id}: {konu}")
                
                response = """<div class="alert alert-success">
                    <h4> Ticket Olusturuldu!</h4>
                    <p>Ticket'ınız basarıyla olusturuldu. Ticket ID: #{ticket_id}</p>
                    <p><strong>Konu:</strong> {konu}<br>
                    <strong>Mesaj:</strong> {mesaj}<br>
                    <strong>Ticket ID:</strong> {ticket_id}</p>
                    <p class="small"><i> Ticketınız #{oper_channel} kanalında yoneticilere bildirildi.</i></p>
                </div>""".format(konu=konu, mesaj=mesaj, ticket_id=ticket_id, oper_channel=bot.config['oper_channel'])
                self._set_headers()
                self.wfile.write(response.encode('utf-8'))
                
        except Exception as e:
            print(f" Ticket ekleme hatası: {e}")
            traceback.print_exc()
            self.send_response(500)
            self.send_header('Content-type', 'text/html')
            self.send_header('Access-Control-Allow-Origin', '*')
            self.end_headers()
            error_html = f"""<div class="alert alert-danger">
                <h4> Hata!</h4>
                <p>{str(e)}</p>
            </div>"""
            self.wfile.write(error_html.encode('utf-8'))
        
    def _validate_email(self, email: str) -> bool:
        """Email validasyonu"""
        pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
        return bool(re.match(pattern, email))
        
    def _validate_ip(self, ip_addr: str) -> bool:
        """IP adresi validasyonu"""
        try:
            ipaddress.ip_address(ip_addr)
            return True
        except:
            return False
    
    def _generate_main_page(self, bot):
        """Ana sayfa HTML"""
        status_text = "Çevrimici" if bot.irc_socket else "Çevrimdışı"
        status_class = "success" if bot.irc_socket else "danger"
        oper_status = " OPER" if bot.is_oper else " USER"
        auth_status = " AUTH" if bot.authenticated else " NOAUTH"
        
        # Bağlı kanallar
        channels_list = ""
        for channel in bot.config['channels']:
            channels_list += f"<span class='badge bg-secondary'>{channel}</span> "
        
        # Bekleyen oper başvuruları sayısı
        pending_apps = sum(1 for app in bot.oper_applications.values() if app.get('status') == 'pending')
        
        return f"""<!DOCTYPE html>
<html lang="tr">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>TutkuFM XLine Bot Paneli v{bot.config['version']}</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
    <style>
        :root {{
            --primary-color: #667eea;
            --secondary-color: #764ba2;
            --success-color: #28a745;
            --danger-color: #dc3545;
            --warning-color: #ffc107;
            --info-color: #17a2b8;
        }}
        
        body {{
            background: linear-gradient(135deg, var(--primary-color) 0%, var(--secondary-color) 100%);
            min-height: 100vh;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
        }}
        
        .glass-card {{
            background: rgba(255, 255, 255, 0.95);
            backdrop-filter: blur(10px);
            border-radius: 20px;
            border: 1px solid rgba(255, 255, 255, 0.2);
            box-shadow: 0 15px 35px rgba(0, 0, 0, 0.1);
            transition: transform 0.3s, box-shadow 0.3s;
        }}
        
        .glass-card:hover {{
            transform: translateY(-5px);
            box-shadow: 0 20px 40px rgba(0, 0, 0, 0.15);
        }}
        
        .status-badge {{
            font-size: 0.9rem;
            padding: 8px 20px;
            border-radius: 50px;
            font-weight: 600;
        }}
        
        .btn-gradient {{
            background: linear-gradient(135deg, var(--primary-color) 0%, var(--secondary-color) 100%);
            border: none;
            color: white;
            padding: 12px 30px;
            border-radius: 50px;
            font-weight: 600;
            transition: all 0.3s;
        }}
        
        .btn-gradient:hover {{
            transform: translateY(-2px);
            box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2);
            color: white;
        }}
        
        .feature-icon {{
            width: 60px;
            height: 60px;
            background: linear-gradient(135deg, var(--primary-color) 0%, var(--secondary-color) 100%);
            border-radius: 15px;
            display: flex;
            align-items: center;
            justify-content: center;
            color: white;
            font-size: 24px;
            margin-bottom: 20px;
        }}
        
        .stat-card {{
            border-left: 5px solid var(--primary-color);
            padding-left: 20px;
        }}
        
        .progress-custom {{
            height: 10px;
            border-radius: 5px;
            background: rgba(0, 0, 0, 0.1);
        }}
        
        .progress-custom .progress-bar {{
            background: linear-gradient(90deg, var(--primary-color) 0%, var(--secondary-color) 100%);
            border-radius: 5px;
        }}
        
        .nav-tabs .nav-link {{
            border: none;
            color: #666;
            font-weight: 600;
            padding: 10px 20px;
        }}
        
        .nav-tabs .nav-link.active {{
            background: linear-gradient(135deg, var(--primary-color) 0%, var(--secondary-color) 100%);
            color: white;
            border-radius: 10px;
        }}
        
        .form-control-custom {{
            border: 2px solid #e0e0e0;
            border-radius: 10px;
            padding: 12px 15px;
            transition: all 0.3s;
        }}
        
        .form-control-custom:focus {{
            border-color: var(--primary-color);
            box-shadow: 0 0 0 0.25rem rgba(102, 126, 234, 0.25);
        }}
        
        .footer {{
            background: rgba(0, 0, 0, 0.2);
            color: white;
            padding: 20px 0;
            margin-top: 40px;
            border-radius: 20px 20px 0 0;
        }}
    </style>
</head>
<body>
    <div class="container py-5">
        <!-- Header -->
        <div class="glass-card p-5 mb-5 text-center">
            <div class="row align-items-center">
                <div class="col-md-2">
                    <div class="feature-icon mx-auto">
                        <i class="fas fa-robot"></i>
                    </div>
                </div>
                <div class="col-md-8">
                    <h1 class="display-4 fw-bold mb-2"> Tutku XLine Bot v{bot.config['version']}</h1>
                    <p class="lead mb-3">Profesyonel IRC Bot ve Web Panel Kontrol Merkezi</p>
                    <span class="status-badge bg-{status_class} text-white">
                        {status_text}
                    </span>
                </div>
                <div class="col-md-2 text-end">
                    <div class="small text-muted">Renk Sistemi Aktif</div>
                    <div class="small">{datetime.now().strftime('%d.%m.%Y %H:%M')}</div>
                </div>
            </div>
        </div>
        
        <!-- İstatistikler -->
        <div class="row mb-5">
            <div class="col-md-3">
                <div class="glass-card p-4 h-100">
                    <div class="stat-card">
                        <div class="text-muted mb-2"><i class="fas fa-signal me-2"></i>Bot Durumu</div>
                        <h3 class="fw-bold">{oper_status}</h3>
                        <div class="small">{auth_status}</div>
                    </div>
                </div>
            </div>
            <div class="col-md-3">
                <div class="glass-card p-4 h-100">
                    <div class="stat-card">
                        <div class="text-muted mb-2"><i class="fas fa-clock me-2"></i>Çalışma Süresi</div>
                        <h3 class="fw-bold">{bot.get_uptime()}</h3>
                        <div class="small">Baslangıc: {datetime.fromtimestamp(bot.start_time).strftime('%H:%M')}</div>
                    </div>
                </div>
            </div>
            <div class="col-md-3">
                <div class="glass-card p-4 h-100">
                    <div class="stat-card">
                        <div class="text-muted mb-2"><i class="fas fa-hashtag me-2"></i>Kanallar</div>
                        <h3 class="fw-bold">{len(bot.config['channels'])}</h3>
                        <div class="small">{channels_list}</div>
                    </div>
                </div>
            </div>
            <div class="col-md-3">
                <div class="glass-card p-4 h-100">
                    <div class="stat-card">
                        <div class="text-muted mb-2"><i class="fas fa-users me-2"></i>Oper Başvuruları</div>
                        <h3 class="fw-bold">{pending_apps}</h3>
                        <div class="small">Bekleyen basvuru</div>
                    </div>
                </div>
            </div>
        </div>
        
        <!-- Ana İçerik -->
        <div class="row">
            <!-- Sol Panel -->
            <div class="col-md-8">
                <!-- Hızlı Erişim Butonları -->
                <div class="glass-card p-4 mb-4">
                    <h4 class="fw-bold mb-4"><i class="fas fa-bolt me-2"></i>Hızlı Erişim</h4>
                    <div class="row g-3">
                        <div class="col-6 col-md-3">
                            <a href="/?[Nick-Bilgi]" class="btn btn-outline-primary w-100 py-3">
                                <i class="fas fa-users fa-2x mb-2"></i><br>
                                Nickler
                            </a>
                        </div>
                        <div class="col-6 col-md-3">
                            <a href="/?[Kanal-Bilgi]" class="btn btn-outline-primary w-100 py-3">
                                <i class="fas fa-hashtag fa-2x mb-2"></i><br>
                                Kanallar
                            </a>
                        </div>
                        <div class="col-6 col-md-3">
                            <a href="/?[Top10-Bilgi]" class="btn btn-outline-warning w-100 py-3">
                                <i class="fas fa-trophy fa-2x mb-2"></i><br>
                                Top 10
                            </a>
                        </div>
                        <div class="col-6 col-md-3">
                            <a href="/?[Radyo-Bilgi]" class="btn btn-outline-success w-100 py-3">
                                <i class="fas fa-music fa-2x mb-2"></i><br>
                                Radyo
                            </a>
                        </div>
                        <div class="col-6 col-md-3">
                            <a href="/?[Armagan-Bilgi]" class="btn btn-outline-success w-100 py-3">
                                <i class="fas fa-gift fa-2x mb-2"></i><br>
                                Armagan
                            </a>
                        </div>
                        <div class="col-6 col-md-3">
                            <a href="/?[Yntc-list]" class="btn btn-outline-danger w-100 py-3">
                                <i class="fas fa-shield-alt fa-2x mb-2"></i><br>
                                Adminler
                            </a>
                        </div>
                        <div class="col-6 col-md-3">
                            <a href="/?[Ticket-List]" class="btn btn-outline-info w-100 py-3">
                                <i class="fas fa-ticket-alt fa-2x mb-2"></i><br>
                                Ticketlar
                            </a>
                        </div>
                        <div class="col-6 col-md-3">
                            <a href="/api/oper_applications" target="_blank" class="btn btn-outline-warning w-100 py-3">
                                <i class="fas fa-user-plus fa-2x mb-2"></i><br>
                                Başvurular
                            </a>
                        </div>
                    </div>
                </div>
                
                <!-- Sistem Bilgileri -->
                <div class="glass-card p-4">
                    <h4 class="fw-bold mb-4"><i class="fas fa-info-circle me-2"></i>Sistem Bilgileri</h4>
                    <div class="row">
                        <div class="col-md-6">
                            <table class="table table-sm">
                                <tr><td><strong>IRC Sunucu:</strong></td><td>{bot.config['server']}:{bot.config['port']}</td></tr>
                                <tr><td><strong>Bot Nick:</strong></td><td>{bot.config['nickname']}</td></tr>
                                <tr><td><strong>Oper Nick:</strong></td><td>{bot.config.get('oper_nick', 'Yok')}</td></tr>
                                <tr><td><strong>Sahip:</strong></td><td>{bot.config.get('owner', 'Bilinmiyor')}</td></tr>
                            </table>
                        </div>
                        <div class="col-md-6">
                            <table class="table table-sm">
                                <tr><td><strong>Web Port:</strong></td><td>{bot.config.get('web_port', 8080)}</td></tr>
                                <tr><td><strong>Domain:</strong></td><td>{bot.config.get('web_domain', 'localhost')}</td></tr>
                                <tr><td><strong>Delimiter:</strong></td><td>'{bot.config.get('web_delimiter', '¿')}'</td></tr>
                                <tr><td><strong>Komut Prefix:</strong></td><td>{bot.config.get('command_prefix', '!')}</td></tr>
                            </table>
                        </div>
                    </div>
                    
                    <!-- Renk ve Tema Bilgisi -->
                    <div class="mt-3">
                        <h6><i class="fas fa-palette me-2"></i>Renk Sistemi</h6>
                        <p class="small mb-1"><strong>Komut:</strong> !anarenk 4 7 8 3 12 13 6</p>
                        <p class="small mb-1"><strong>Temalar:</strong> !tema default/dark/bright/rainbow</p>
                        <p class="small mb-1"><strong>Renkler:</strong> !renkler (renk listesi)</p>
                    </div>
                    
                    <!-- Bağlantı Testi -->
                    <div class="mt-4">
                        <button onclick="testConnection()" class="btn-gradient">
                            <i class="fas fa-plug me-2"></i>Baglantıyı Test Et
                        </button>
                        <button onclick="refreshStatus()" class="btn btn-outline-secondary ms-2">
                            <i class="fas fa-sync-alt me-2"></i>Yenile
                        </button>
                        <div id="testResult" class="mt-3"></div>
                    </div>
                </div>
            </div>
            
            <!-- Sağ Panel -->
            <div class="col-md-4">
                <!-- Hızlı Formlar -->
                <div class="glass-card p-4 mb-4">
                    <h4 class="fw-bold mb-4"><i class="fas fa-paper-plane me-2"></i>Hızlı İşlemler</h4>
                    
                    <!-- Radyo İstek Formu -->
                    <div class="mb-4">
                        <h6 class="fw-bold"><i class="fas fa-music me-2"></i>Radyo İsteği</h6>
                        <div class="mb-2">
                            <input type="text" id="radioArtist" class="form-control form-control-custom mb-2" placeholder="Sanatcı">
                            <input type="text" id="radioSong" class="form-control form-control-custom mb-2" placeholder="Sarkı">
                            <input type="text" id="radioNick" class="form-control form-control-custom mb-2" placeholder="Nick (opsiyonel)">
                            <textarea id="radioMessage" class="form-control form-control-custom mb-2" rows="2" placeholder="Mesaj (opsiyonel)"></textarea>
                            <button onclick="sendRadioRequest()" class="btn btn-success w-100">
                                <i class="fas fa-paper-plane me-2"></i>İstek Gonder
                            </button>
                        </div>
                    </div>
                    
                    <!-- XLine Bildirim Formu -->
                    <div>
                        <h6 class="fw-bold"><i class="fas fa-exclamation-triangle me-2"></i>XLine Bildirimi</h6>
                        <div class="mb-2">
                            <input type="text" id="xlineNick" class="form-control form-control-custom mb-2" placeholder="Sikayet Edilen Nick">
                            <textarea id="xlineReason" class="form-control form-control-custom mb-2" rows="3" placeholder="Sebep"></textarea>
                            <button onclick="sendXlineReport()" class="btn btn-danger w-100">
                                <i class="fas fa-exclamation-circle me-2"></i>Bildir
                            </button>
                        </div>
                    </div>
                </div>
                
                <!-- Web Panel URL -->
                <div class="glass-card p-4">
                    <h4 class="fw-bold mb-3"><i class="fas fa-link me-2"></i>Web Panel URL</h4>
                    <div class="input-group mb-3">
                        <input type="text" class="form-control form-control-custom" id="webPanelUrl" 
                               value="{bot.config.get('web_domain', 'localhost')}" readonly>
                        <button class="btn btn-outline-primary" onclick="copyUrl()">
                            <i class="fas fa-copy"></i>
                        </button>
                    </div>
                    <p class="small text-muted mb-0">
                        <i class="fas fa-info-circle me-1"></i>
                        Bu URL'yi Tutku web panelinde kullanabilirsiniz.
                    </p>
                </div>
            </div>
        </div>
        
        <!-- Footer -->
        <div class="footer glass-card mt-5">
            <div class="row text-center">
                <div class="col-md-4">
                    <h6><i class="fas fa-server me-2"></i>IRC Sunucusu</h6>
                    <p class="mb-0">{bot.config['server']}</p>
                </div>
                <div class="col-md-4">
                    <h6><i class="fas fa-code me-2"></i>Geliştirici</h6>
                    <p class="mb-0">{bot.config.get('owner', 'Bilinmiyor')}</p>
                </div>
                <div class="col-md-4">
                    <h6><i class="fas fa-heart me-2"></i>TutkuFM</h6>
                    <p class="mb-0">Turkiye'nin En Iyi IRC Radyosu</p>
                </div>
            </div>
        </div>
    </div>
    
    <!-- Scripts -->
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
    <script>
        // Baglantı testi
        async function testConnection() {{
            const resultDiv = document.getElementById('testResult');
            resultDiv.innerHTML = '<div class="alert alert-info">Test ediliyor...</div>';
            
            try {{
                const response = await fetch('/api/status');
                const data = await response.json();
                
                if (data.online) {{
                    resultDiv.innerHTML = `
                        <div class="alert alert-success">
                            <h5> Baglantı Basarılı!</h5>
                            <p><strong>Nick:</strong> ${{data.nick}}</p>
                            <p><strong>Durum:</strong> ${{data.oper ? 'OPER' : 'USER'}}</p>
                            <p><strong>Uptime:</strong> ${{data.uptime}}</p>
                        </div>
                    `;
                }} else {{
                    resultDiv.innerHTML = '<div class="alert alert-danger"> Bot cevrimdisi gorunuyor</div>';
                }}
            }} catch (error) {{
                resultDiv.innerHTML = '<div class="alert alert-danger"> Baglantı hatası: ' + error.message + '</div>';
            }}
        }}
        
        // URL kopyalama
        function copyUrl() {{
            const urlInput = document.getElementById('webPanelUrl');
            urlInput.select();
            urlInput.setSelectionRange(0, 99999);
            navigator.clipboard.writeText(urlInput.value);
            
            // Bildirim goster
            const originalText = urlInput.value;
            urlInput.value = ' Kopyalandı!';
            setTimeout(() => {{
                urlInput.value = originalText;
            }}, 2000);
        }}
        
        // Radyo isteği gonder
        async function sendRadioRequest() {{
            const artist = document.getElementById('radioArtist').value;
            const song = document.getElementById('radioSong').value;
            const nick = document.getElementById('radioNick').value || 'WebUser';
            const message = document.getElementById('radioMessage').value;
            
            if (!artist || !song) {{
                alert('Lutfen sanatcı ve sarkı adı girin!');
                return;
            }}
            
            const data = `[Radyo-istek]¿${{nick}}¿${{artist}}¿${{song}}¿${{message}}¿${{getClientIP()}}`;
            
            try {{
                const response = await fetch('/', {{
                    method: 'POST',
                    headers: {{ 'Content-Type': 'application/x-www-form-urlencoded' }},
                    body: data
                }});
                
                const result = await response.text();
                showAlert('success', ' İstek Gonderildi!', 'DJ\\'lere iletildi.');
                
                // Formu temizle
                document.getElementById('radioArtist').value = '';
                document.getElementById('radioSong').value = '';
                document.getElementById('radioMessage').value = '';
                
            }} catch (error) {{
                showAlert('danger', ' Hata!', error.message);
            }}
        }}
        
        // XLine bildirimi gonder
        async function sendXlineReport() {{
            const nick = document.getElementById('xlineNick').value;
            const reason = document.getElementById('xlineReason').value;
            
            if (!nick || !reason) {{
                alert('Lutfen nick ve sebep girin!');
                return;
            }}
            
            const data = `[Xline-bildirim]¿${{nick}}¿${{reason}}¿${{getClientIP()}}`;
            
            try {{
                const response = await fetch('/', {{
                    method: 'POST',
                    headers: {{ 'Content-Type': 'application/x-www-form-urlencoded' }},
                    body: data
                }});
                
                const result = await response.text();
                showAlert('warning', ' Bildirim Gonderildi!', 'Yoneticilere iletildi.');
                
                // Formu temizle
                document.getElementById('xlineNick').value = '';
                document.getElementById('xlineReason').value = '';
                
            }} catch (error) {{
                showAlert('danger', ' Hata!', error.message);
            }}
        }}
        
        // Durumu yenile
        function refreshStatus() {{
            location.reload();
        }}
        
        // Alert goster
        function showAlert(type, title, message) {{
            const alertDiv = document.createElement('div');
            alertDiv.className = `alert alert-${{type}} alert-dismissible fade show`;
            alertDiv.innerHTML = `
                <h5>${{title}}</h5>
                <p>${{message}}</p>
                <button type="button" class="btn-close" data-bs-dismiss="alert"></button>
            `;
            
            // Sayfanın ustune ekle
            document.querySelector('.container').insertBefore(alertDiv, document.querySelector('.container').firstChild);
            
            // 5 saniye sonra kaldır
            setTimeout(() => {{
                alertDiv.remove();
            }}, 5000);
        }}
        
        // Client IP al (yaklaşık)
        function getClientIP() {{
            return 'web_panel_user';
        }}
        
        // Sayfa yuklendiğinde baglantıyı test et
        document.addEventListener('DOMContentLoaded', () => {{
            // 30 saniyede bir durumu kontrol et
            setInterval(async () => {{
                try {{
                    const response = await fetch('/api/status');
                    const data = await response.json();
                    updateStatusBadge(data.online);
                }} catch (error) {{
                    updateStatusBadge(false);
                }}
            }}, 30000);
        }});
        
        function updateStatusBadge(online) {{
            const badge = document.querySelector('.status-badge');
            if (online) {{
                badge.className = 'status-badge bg-success text-white';
                badge.innerHTML = ' Cevrimici';
            }} else {{
                badge.className = 'status-badge bg-danger text-white';
                badge.innerHTML = ' Cevrimdisi';
            }}
        }}
    </script>
</body>
</html>"""
    
    def _generate_error_page(self, message):
        """Hata sayfası HTML"""
        return f"""<!DOCTYPE html>
<html lang="tr">
<head>
    <meta charset="UTF-8">
    <title>Hata - TutkuFM Bot</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
    <style>
        body {{ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); min-height: 100vh; display: flex; align-items: center; }}
        .error-card {{ background: white; border-radius: 20px; padding: 40px; max-width: 600px; margin: 0 auto; }}
    </style>
</head>
<body>
    <div class="container">
        <div class="error-card text-center">
            <h1 class="display-1 text-danger">😕</h1>
            <h2 class="mb-4">Bir Hata Olustu</h2>
            <p class="lead mb-4">{message}</p>
            <a href="/" class="btn btn-primary btn-lg">
                <i class="fas fa-home me-2"></i>Ana Sayfaya Don
            </a>
        </div>
</body>
</html>"""

# ====================== TUTKU BOT ======================
class TutkuBot:
    def __init__(self):
        self.config = self.load_config()
        self.irc_socket = None
        self.running = True
        self.authenticated = False
        self.is_oper = False
        self.web_server = None
        self.web_thread = None
        self.start_time = time.time()
        self.rate_limiter = RateLimiter()
        self.last_cleanup = time.time()
        self.backup_interval = 3600
        self.connection_attempts = 0
        self.max_connection_attempts = 10
        self.connection_delay = 5
        self.oper_retry_count = 0
        self.max_oper_retries = 3
        
        # 🌈 RENK ve TEMA AYARLARI
        self.current_theme = "default"
        self.colors = ThemeSystem.apply_theme(self.current_theme)
        self.user_color_prefs = {}  # Kullanıcı renk tercihleri
        self.channel_joined = {}  # Katıldığı kanalların takibi
        
        # Web panelden gelen verileri saklamak için
        self.web_data = {
            'nick_info': [],
            'channel_info': [],
            'top10_info': [],
            'radio_info': {},
            'oper_list': [],
            'last_requests': {}
        }
        
        # Oper başvuruları için
        self.oper_applications = {}
        self.next_app_id = 1
        self.oper_application_bans = {}
        
        # Ban listesi için önbellek
        self.ban_cache = {
            'xlines': [],
            'glines': [],
            'klines': [],
            'sqlines': [],
            'spamfilters': []
        }
        
        # Ticket sistemi için
        self.tickets = {}
        self.next_ticket_id = 1
        
        # Puan sistemi için
        self.user_points = {}
        
        # Yedekten yükle
        self.load_backup()
        
        # Bot instance'ını WebHandler'a set et
        WebHandler.bot = self
    
    def generate_application_id(self):
        """Başvuru ID'si oluştur"""
        app_id = self.next_app_id
        self.next_app_id += 1
        return app_id
    
    def load_config(self) -> Dict:
        """Bot yapılandırma dosyasını yükler"""
        config = {
            # IRC Sunucu Ayarları
            'server': 'irc.gevezeci.com',
            'port': 6667,
            'ssl': False,
            
            # NICK BİLGİLERİ
            'nickname': 'Yorumcu',
            'nick_password': '5159293sa',
            'username': 'xlinebot',
            'realname': 'Tutku XLine Bot v3.3',
            
            # OPER BİLGİLERİ
            'oper_nick': 'Sado',
            'oper_pass': '.wqerty12345.',
            
            # Kanallar
            'channels': ['#help', '#admin', '#mavifm', '#opers'],
            'excluded_channels': ['#oxm', '#AskOyun', '#mobil', '#general', '#chat', '#lobby'],
            'oper_channel': '#admin',
            'radio_channel': '#mavifm',
            
            # Komut prefix
            'command_prefix': '!',
            
            # Admin nickleri
            'admin_nicks': ['NS-HELP', 'SADO', 'KALPSIZ', 'Q-CYCLE', 'CS-HELP', 'Q-WEB', 'HELP'],
            
            # Bot bilgileri
            'owner': 'Sado',
            'version': '3.3',
            
            # Web Panel Ayarları
            'web_host': '217.18.208.203',
            'web_port': 8080,
            'web_domain': 'https://tutku.jetcozum.xyz',
            
            # Web panelden gelen istekler için ayırıcı
            'web_delimiter': '¿',
            
            # Zaman ayarları
            'reconnect_delay': 5,
            'ping_timeout': 60,
            'ping_interval': 120,
            
            # Güvenlik ayarları
            'ip_whitelist': [
                '127.0.0.1',
                '192.168.0.0/16',
                '10.0.0.0/8'
            ],
            
            # Rate limiting
            'rate_limit_max': 30,
            'rate_limit_window': 60,
            
            # Log ayarları
            'log_requests': True,
            'log_file': 'tutkubot.log',
            'debug_mode': True,
            
            # Bağlantı ayarları
            'immediate_oper': True,
            'oper_retry_interval': 10,
            'force_oper_timeout': 30,
        }
        
        # Config dosyasını kontrol et
        config_file = 'tutkubot.json'
        if os.path.exists(config_file):
            try:
                with open(config_file, 'r', encoding='utf-8') as f:
                    file_config = json.load(f)
                    # Varsayılan değerleri güncelle
                    for key, value in file_config.items():
                        config[key] = value
                print(f"  Config dosyası '{config_file}' yüklendi")
            except Exception as e:
                print(f"  Config dosyası okunamadı: {e}")
        else:
            print(f"  Config dosyası '{config_file}' bulunamadı, varsayılanlar kullanılıyor")
            # Config dosyasını oluştur
            try:
                with open(config_file, 'w', encoding='utf-8') as f:
                    json.dump(config, f, indent=4, ensure_ascii=False)
                print(f"  Varsayılan config dosyası oluşturuldu: {config_file}")
            except Exception as e:
                print(f"  Config dosyası oluşturulamadı: {e}")
                
        return config
    
    def send_raw_with_colors(self, target: str, message: str):
        """Renk kodlarını koruyarak raw mesaj gönder"""
        try:
            # Mesajı doğrudan gönder (türkçe karakter zaten düzeltiliyor)
            self.irc_socket.send(f"{message}\r\n".encode('utf-8'))
            if self.config['debug_mode']:
                print(f"→ (Renkli) {message[:200]}")
        except Exception as e:
            print(f" Renkli mesaj gönderme hatası: {e}")
    
    def colorize(self, text: str, color_type: str = "info") -> str:
        """Metni renklendir"""
        color_code = self.colors.get(color_type, "15")
        return IRCColors.colorize(text, color_code)
    
    def bold(self, text: str) -> str:
        """Metni kalın yap"""
        return IRCColors.bold(text)
    
    def send_privmsg(self, target: str, message: str, color_type: str = "info"):
        """Renkli PRIVMSG gönder"""
        # Color kodunu temala göre al
        if color_type in self.colors:
            color_code = self.colors[color_type]
            colored_msg = IRCColors.colorize(message, color_code)
        else:
            colored_msg = message
            
        # Türkçe karakterleri ASCII'ye çevir
        message_ascii = self._replace_turkish_chars(colored_msg)
        self.send_raw(f"PRIVMSG {target} :{message_ascii}")
    
    def send_notice(self, target: str, message: str, color_type: str = "info"):
        """Renkli NOTICE gönder"""
        if color_type in self.colors:
            color_code = self.colors[color_type]
            colored_msg = IRCColors.colorize(message, color_code)
        else:
            colored_msg = message
        
        # Türkçe karakterleri ASCII'ye çevir
        message_ascii = self._replace_turkish_chars(colored_msg)
        self.send_raw(f"NOTICE {target} :{message_ascii}")
    
    def _replace_turkish_chars(self, text: str) -> str:
        """Türkçe karakterleri ASCII'ye çevir"""
        turkish_chars = {
            'ı': 'i', 'İ': 'I', 'ğ': 'g', 'Ğ': 'G',
            'ü': 'u', 'Ü': 'U', 'ş': 's', 'Ş': 'S',
            'ö': 'o', 'Ö': 'O', 'ç': 'c', 'Ç': 'C',
            'â': 'a', 'Â': 'A', 'î': 'i', 'Î': 'I',
            'û': 'u', 'Û': 'U'
        }
        
        result = ''
        for char in text:
            if char in turkish_chars:
                result += turkish_chars[char]
            else:
                result += char
        
        return result
    
    def generate_random_string(self, length: int = 8) -> str:
        """Rastgele string oluştur"""
        return ''.join(random.choices(string.ascii_letters + string.digits, k=length))
    
    def validate_nick(self, nick: str) -> bool:
        """Nick validasyonu"""
        if not nick or len(nick) < 2 or len(nick) > 30:
            return False
        
        if not nick[0].isalpha():
            return False
        
        valid_chars = set('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789[]\\`_^{|}-')
        return all(c in valid_chars for c in nick)
    
    def get_channel_users(self, channel: str) -> List[str]:
        """Kanaldaki kullanıcıları getir"""
        return []
    
    def handle_who_response(self, line: str):
        """WHO komutu yanıtlarını işle"""
        if '352' in line:
            parts = line.split()
            if len(parts) >= 8:
                channel = parts[3]
                user = parts[7]
                if self.config['debug_mode']:
                    print(f" {channel}: {user}")
    
    def cleanup_old_tickets(self):
        """Eski ticket'ları temizle"""
        current_time = datetime.now()
        tickets_to_remove = []
        
        for ticket_id, ticket in self.tickets.items():
            try:
                created = datetime.fromisoformat(ticket.get('created', '2000-01-01'))
                days_old = (current_time - created).days
                
                if days_old > 30:
                    tickets_to_remove.append(ticket_id)
            except:
                pass
        
        for ticket_id in tickets_to_remove:
            del self.tickets[ticket_id]
        
        if tickets_to_remove:
            print(f" {len(tickets_to_remove)} eski ticket temizlendi")
    
    def backup_data(self):
        """Verileri yedekle"""
        try:
            backup_data = {
                'tickets': self.tickets,
                'user_points': self.user_points,
                'oper_applications': self.oper_applications,
                'oper_application_bans': self.oper_application_bans,
                'next_ticket_id': self.next_ticket_id,
                'next_app_id': self.next_app_id,
                'backup_time': datetime.now().isoformat()
            }
            
            with open('backup.json', 'w', encoding='utf-8') as f:
                json.dump(backup_data, f, indent=2, ensure_ascii=False)
            
            print(f" Veriler yedeklendi: {len(self.tickets)} ticket, {len(self.oper_applications)} basvuru")
            return True
        except Exception as e:
            print(f" Yedekleme hatası: {e}")
            return False
    
    def load_backup(self):
        """Yedekten verileri yükle"""
        try:
            if os.path.exists('backup.json'):
                with open('backup.json', 'r', encoding='utf-8') as f:
                    backup_data = json.load(f)
                
                self.tickets = backup_data.get('tickets', {})
                self.user_points = backup_data.get('user_points', {})
                self.oper_applications = backup_data.get('oper_applications', {})
                self.oper_application_bans = backup_data.get('oper_application_bans', {})
                self.next_ticket_id = backup_data.get('next_ticket_id', 1)
                self.next_app_id = backup_data.get('next_app_id', 1)
                
                print(f" Yedek yuklendi: {len(self.tickets)} ticket, {len(self.oper_applications)} basvuru")
                return True
        except Exception as e:
            print(f" Yedek yukleme hatası: {e}")
        
        return False
    
    def log_action(self, action_type: str, message: str):
        """Log kaydı"""
        timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        log_entry = f"[{timestamp}] [{action_type}] {message}"
        
        print(log_entry)
        
        try:
            log_file = self.config.get('log_file', 'bot.log')
            with open(log_file, 'a', encoding='utf-8') as f:
                f.write(log_entry + '\n')
        except Exception as e:
            print(f" Log yazma hatası: {e}")
    
    def start_web_server(self):
        """Web panel server'ı başlatır"""
        try:
            # Server'ı başlat
            web_host = self.config.get('web_host', '0.0.0.0')
            web_port = self.config.get('web_port', 8080)
            server_address = (web_host, web_port)
            self.web_server = HTTPServer(server_address, WebHandler)
            
            print(f" Web panel baslatıldı: http://{web_host}:{web_port}")
            print(f" Domain: {self.config.get('web_domain', 'localhost')}")
            print(f" Delimiter: '{self.config.get('web_delimiter', '¿')}'")
            
            self.web_thread = threading.Thread(target=self.web_server.serve_forever, daemon=True)
            self.web_thread.start()
            
            return True
            
        except Exception as e:
            print(f" Web server hatası: {e}")
            traceback.print_exc()
            return False
    
    def connect_irc(self):
        """IRC sunucusuna bağlanır ve login yapar"""
        try:
            print(f" {self.config['server']}:{self.config['port']} baglanılıyor...")
            
            if self.config.get('ssl', False):
                context = ssl.create_default_context()
                sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                self.irc_socket = context.wrap_socket(sock, server_hostname=self.config['server'])
            else:
                self.irc_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            
            self.irc_socket.connect((self.config['server'], self.config['port']))
            self.irc_socket.settimeout(self.config.get('ping_timeout', 60))
            
            print(" Soket baglantısı basarılı!")
            
            # Hemen login yap
            print(f" Login yapılıyor: {self.config['nickname']}")
            self.send_raw(f"NICK {self.config['nickname']}")
            self.send_raw(f"USER {self.config['username']} 0 * :{self.config['realname']}")
            
            return True
            
        except Exception as e:
            print(f" Baglantı hatası: {e}")
            if self.config.get('debug_mode', False):
                traceback.print_exc()
            return False
    
    def wait_for_welcome(self):
        """Hoşgeldin mesajlarını bekler"""
        print(" Sunucu hosgeldin mesajı bekleniyor...")
        start_time = time.time()
        timeout = 30
        
        while time.time() - start_time < timeout:
            try:
                data = self.irc_socket.recv(4096).decode('utf-8', errors='ignore')
                if not data:
                    return False
                
                lines = data.split('\r\n')
                for line in lines:
                    line = line.strip()
                    if line:
                        print(f" {line}")
                        
                        # PING/PONG
                        if line.startswith('PING'):
                            self.send_raw(line.replace('PING', 'PONG'))
                            print(" PING/PONG")
                        
                        # 001-004 mesajları (giriş basarılı)
                        elif '001' in line or '002' in line or '003' in line or '004' in line:
                            print(" Sunucuya giriş yapıldı")
                            return True
                
            except socket.timeout:
                continue
            except:
                return False
        
        print(" Sunucu hosgeldin mesajı zaman aşımı")
        return False
    
    def identify_and_oper(self):
        """NickServ'e şifre gönderir ve OPER olur"""
        try:
            # 1. NickServ'e şifre gönder
            nick_password = self.config.get('nick_password')
            if nick_password:
                print(" NickServ'e sifre gonderiliyor...")
                self.send_raw(f"PRIVMSG NickServ :IDENTIFY {nick_password}")
                time.sleep(3)
            
            # 2. Hemen OPER girişi yap
            oper_nick = self.config.get('oper_nick')
            oper_pass = self.config.get('oper_pass')
            if oper_nick and oper_pass:
                print(f" OPER girişi yapılıyor: {oper_nick}")
                self.send_raw(f"OPER {oper_nick} {oper_pass}")
                time.sleep(2)
            
            return True
        except Exception as e:
            print(f" Identify/Oper hatası: {e}")
            return False
    
    def join_channels(self):
        """SADECE BELİRLİ KANALLARA KATILIR - TEKRARLI GİRİŞ ÖNLEYİCİ"""
        print(" Kanallara katılınıyor...")
        
        # Önce channel_joined listesini temizle
        self.channel_joined = {}
        
        # Kanalları sırayla katıl
        channels = self.config.get('channels', [])
        for channel in channels:
            # Global kanallara girmeyi engelle
            excluded_channels = self.config.get('excluded_channels', [])
            if channel.lower() in [c.lower() for c in excluded_channels]:
                print(f" {channel} kanalına girmiyor (engelli)")
                continue
            
            # Zaten katılmışsa tekrar katılma
            if self.channel_joined.get(channel, False):
                print(f" {channel} zaten katılmış, tekrar katılmıyor")
                continue
                
            self.send_raw(f"JOIN {channel}")
            time.sleep(1.5)  # Daha uzun bekle
            print(f" {channel} kanalına katıldı")
            
            # Kanalı katılmış olarak işaretle
            self.channel_joined[channel] = True
            
            # SADECE OPER KANALINA 1 KEZ HOSGELDIN MESAJI GÖNDER
            oper_channel = self.config.get('oper_channel', '#opers')
            if channel == oper_channel:
                time.sleep(3)  # Daha uzun bekle
                welcome_msg = IRCColors.rainbow(f" {self.config['nickname']} botu baslatıldı! v{self.config['version']}", [4, 7, 8, 3, 12])
                self.send_raw(f"PRIVMSG {channel} :{welcome_msg}")
                
                # Bot durumunu belirt
                status_msg = " Bot aktif! Komutlar icin !help yazın."
                self.send_privmsg(channel, status_msg, color_type="success")
                
                # Oper olduysa bildir (1 KEZ)
                if self.is_oper:
                    time.sleep(2)
                    oper_msg = IRCColors.colorize(f" {self.config['nickname']} oper olarak giriş yaptı!", "04")
                    self.send_raw(f"PRIVMSG {channel} :{oper_msg}")
    
    def force_oper_login(self):
        """OPER girişini zorla"""
        print(" Zorla OPER girişi deneniyor...")
        
        self.oper_retry_count = 0
        
        oper_nick = self.config.get('oper_nick')
        oper_pass = self.config.get('oper_pass')
        
        if not oper_nick or not oper_pass:
            print("  OPER bilgileri yok!")
            return False
        
        for i in range(3):
            print(f" OPER denemesi {i+1}/3")
            self.send_raw(f"OPER {oper_nick} {oper_pass}")
            time.sleep(2)
            
            self.send_raw(f"PING :{int(time.time())}")
            time.sleep(1)
        
        time.sleep(3)
        print(" Son OPER denemesi...")
        self.send_raw(f"OPER {oper_nick} {oper_pass}")
        
        self.send_raw(f"WHOIS {self.config['nickname']}")
        
        print(" Zorla OPER girişi tamamlandı")
        return True
    
    def check_oper_status(self):
        """OPER durumunu kontrol et"""
        if self.is_oper:
            return True
        
        self.send_raw(f"WHOIS {self.config['nickname']}")
        time.sleep(1)
        
        self.send_raw(f"MODE {self.config['nickname']}")
        time.sleep(1)
        
        return False
    
    def send_raw(self, message: str):
        """IRC sunucusuna raw mesaj gönderir"""
        if self.irc_socket:
            try:
                # Türkçe karakterleri ASCII'ye çevir
                message_ascii = self._replace_turkish_chars(message)
                self.irc_socket.send(f"{message_ascii}\r\n".encode('utf-8'))
                if self.config.get('debug_mode', False):
                    print(f"→ {message_ascii[:200]}")
            except Exception as e:
                print(f" Gonderim hatası: {e}")
    
    def handle_server_message(self, line: str):
        """Sunucu mesajlarını işler"""
        # PING/PONG
        if line.startswith('PING'):
            pong_msg = line.split()[1] if len(line.split()) > 1 else ''
            self.send_raw(f"PONG {pong_msg}")
            print(f" PING/PONG cevap verildi")
        
        # MOTD bitişi (001-004) - Giriş basarılı
        elif '001' in line or '002' in line or '003' in line or '004' in line:
            print(" Sunucuya giriş yapıldı")
            
            # Hemen login prosedurunu baslat
            time.sleep(2)
            
            # 1. NickServ sifresi gonder
            nick_password = self.config.get('nick_password')
            if nick_password:
                self.send_raw(f"PRIVMSG NickServ :IDENTIFY {nick_password}")
                time.sleep(3)
            
            # 2. Hemen OPER girişi yap
            if self.config.get('immediate_oper', True):
                print(" Hemen OPER girişi yapılıyor...")
                oper_nick = self.config.get('oper_nick')
                oper_pass = self.config.get('oper_pass')
                if oper_nick and oper_pass:
                    self.send_raw(f"OPER {oper_nick} {oper_pass}")
                    time.sleep(2)
            
            # 3. Kanallara katıl
            self.join_channels()
        
        # Oper yetkisi alındı
        elif 'are now an IRC Operator' in line or 'MODE' in line and '+o' in line and self.config['nickname'] in line:
            print(" OPER YETKISI ALINDI!")
            self.is_oper = True
            oper_channel = self.config.get('oper_channel', '#opers')
            self.send_privmsg(oper_channel, 
                            f" {self.config['nickname']} oper olarak giriş yaptı!", 
                            color_type="success")
            self.oper_retry_count = 0
        
        # NickServ mesajları
        elif 'NickServ' in line or 'IDENTIFY' in line:
            line_lower = line.lower()
            if 'identified' in line_lower or 'giriş yaptınız' in line_lower or 'successfully' in line_lower:
                print(" Nick sifresi dogrulandi!")
                self.authenticated = True
                
                if not self.is_oper and self.config.get('immediate_oper', True):
                    print(" NickServ auth sonrası OPER girişi...")
                    oper_nick = self.config.get('oper_nick')
                    oper_pass = self.config.get('oper_pass')
                    if oper_nick and oper_pass:
                        self.send_raw(f"OPER {oper_nick} {oper_pass}")
            elif 'invalid' in line_lower or 'incorrect' in line_lower or 'yanlış' in line_lower:
                print(" Nick sifresi hatali!")
                self.authenticated = False
        
        # INVITE mesajı alırsa (izinli değilse katılma)
        elif 'INVITE' in line and self.config['nickname'] in line:
            parts = line.split()
            if len(parts) >= 4:
                channel = parts[3].lstrip(':')
                channels = self.config.get('channels', [])
                if channel not in channels:
                    print(f" Davet reddedildi: {channel} (izinli değil)")
                else:
                    self.send_raw(f"JOIN {channel}")
                    print(f" Davet kabul edildi: {channel}")
        
        # WHOIS yanıtı - OPER durumu kontrolü
        elif '307' in line and self.config['nickname'] in line:
            print(" Nick kayıtlı")
        elif '313' in line and self.config['nickname'] in line:
            print(" WHOIS: IRC Operator oldugu goruldu!")
            self.is_oper = True
        
        # WHO yanıtları
        elif '352' in line:
            self.handle_who_response(line)
    
    def handle_privmsg(self, sender: str, target: str, message: str):
        """PRIVMSG mesajlarını işler"""
        nick = sender.split('!')[0] if '!' in sender else sender
        
        if self.config.get('debug_mode', False):
            print(f" {nick} -> {target}: {message}")
        
        # PM (Ozel mesaj)
        if target == self.config['nickname']:
            self.handle_private_message(nick, message)
            return
        
        # Kanal komutları
        command_prefix = self.config.get('command_prefix', '!')
        if message.startswith(command_prefix):
            self.handle_command(nick, target, message)
    
    def handle_command(self, nick: str, target: str, message: str):
        """Komutları işler"""
        command_prefix = self.config.get('command_prefix', '!')
        cmd_parts = message[len(command_prefix):].split()
        if not cmd_parts:
            return
        
        command = cmd_parts[0].lower()
        args = cmd_parts[1:]
        
        # 🌈 RENK ve TEMA KOMUTLARI
        if command == 'anarenk' or command == 'renkayarla':
            self.handle_color_command(nick, args, target)
        
        elif command == 'tema':
            self.handle_theme_command(nick, args, target)
        
        elif command == 'renkler':
            self.show_colors(nick, target)
        
        #  ADMIN KOMUTLARI
        elif command == 'onaylandi' or command == 'onay':
            self.handle_oper_application_approve(nick, args, target)
        
        elif command == 'reddedildi' or command == 'red':
            self.handle_oper_application_reject(nick, args, target)
        
        elif command == 'basvuruyasak':
            self.handle_oper_application_ban(nick, args, target)
        
        elif command == 'nickkayit':
            self.handle_nick_register(nick, args, target)
        
        elif command == 'forceoper':
            if self.check_admin(nick):
                self.force_oper_login()
                self.send_privmsg(target, " Zorla OPER girişi yapıldı!", color_type="success")
            else:
                self.send_notice(nick, " Bu komut icin admin yetkisi gerekiyor!", color_type="error")
        
        elif command == 'checkoper':
            if self.check_admin(nick):
                status = "OPER" if self.is_oper else "USER"
                self.send_privmsg(target, f" Bot durumu: {status}", color_type="info")
                self.send_privmsg(target, f" Auth: {'EVET' if self.authenticated else 'HAYIR'}", color_type="info")
            else:
                self.send_notice(nick, " Bu komut icin admin yetkisi gerekiyor!", color_type="error")
        
        elif command in ['xline', 'gzline', 'gline', 'kline', 'zline']:
            if self.check_admin(nick):
                self.handle_ban_command(nick, command, args, target)
            else:
                self.send_notice(nick, " Bu komut icin admin yetkisi gerekiyor!", color_type="error")
        
        elif command == 'sqline':
            if self.check_admin(nick):
                self.handle_sqline_command(nick, args, target)
            else:
                self.send_notice(nick, " Bu komut icin admin yetkisi gerekiyor!", color_type="error")
        
        elif command == 'spamfilter':
            if self.check_admin(nick):
                self.handle_spamfilter_command(nick, args, target)
            else:
                self.send_notice(nick, " Bu komut icin admin yetkisi gerekiyor!", color_type="error")
        
        elif command == 'country':
            if self.check_admin(nick):
                self.handle_country_command(nick, args, target)
            else:
                self.send_notice(nick, " Bu komut icin admin yetkisi gerekiyor!", color_type="error")
        
        elif command == 'as':
            if self.check_admin(nick):
                self.handle_as_command(nick, args, target)
            else:
                self.send_notice(nick, " Bu komut icin admin yetkisi gerekiyor!", color_type="error")
        
        #  RADYO KOMUTLARI
        elif command == 'radio':
            self.handle_radio_command(nick, args, target)
        
        #  BİLGİ KOMUTLARI
        elif command == 'komutlar' or command == 'help':
            self.show_help(nick, target)
        
        elif command == 'stats':
            self.show_stats(nick, target)
        
        elif command == 'version':
            version_msg = IRCColors.rainbow(f" {self.config['nickname']} v{self.config['version']} - {self.config.get('owner', 'Sado')}", [4, 7, 8])
            self.send_raw(f"PRIVMSG {target} :{version_msg}")
        
        #  TICKET KOMUTLARI
        elif command == 'ticket':
            self.handle_ticket_command(nick, args, target)
        
        #  PUAN KOMUTLARI
        elif command == 'points':
            self.handle_points_command(nick, args, target)
        
        # 🔧 BOT KOMUTLARI
        elif command == 'join' and self.check_admin(nick):
            self.handle_join_command(nick, args, target)
        
        elif command == 'part' and self.check_admin(nick):
            self.handle_part_command(nick, args, target)
        
        elif command == 'web' or command == 'webpanel':
            self.send_privmsg(target, f" Web Panel: {self.config.get('web_domain', 'localhost')}", color_type="info")
        
        elif command == 'basvurular':
            self.handle_oper_applications_list(nick, target)
        
        else:
            self.send_notice(nick, f" Bilinmeyen komut: {command}. !komutlar yazarak komutları gorebilirsin.", color_type="warning")
    
    def handle_color_command(self, nick: str, args: List[str], target: str):
        """Renk ayarlama komutu"""
        if not args:
            help_msg = IRCColors.rainbow(" Renk Komutları:", [4, 7, 8])
            self.send_raw(f"PRIVMSG {target} :{help_msg}")
            self.send_privmsg(target, "Kullanım: !anarenk <renk1> <renk2> ... veya !anarenk <tema_adi>", color_type="info")
            self.send_privmsg(target, "Ornek: !anarenk 4 7 8 3 12 13 6", color_type="info")
            self.send_privmsg(target, "Renkler: 0:beyaz 1:siyah 2:lacivert 3:koyuyesil 4:kirmizi 5:koyukirmizi 6:mor 7:turuncu 8:sari 9:acikyesil 10:cyan 11:acikcyan 12:mavi 13:acikmor 14:gri 15:acikgri", color_type="info")
            return
        
        # Tema seçimi
        if args[0] in ThemeSystem.THEMES:
            self.current_theme = args[0]
            self.colors = ThemeSystem.apply_theme(self.current_theme)
            self.send_privmsg(target, f"Tema '{args[0]}' uygulandı!", color_type="success")
            return
        
        # Ozel renk pattern'i
        try:
            pattern = []
            color_names = []
            for color_code in args[:7]:  # Max 7 renk
                if color_code in IRCColors.COLOR_MAP:
                    pattern.append(int(IRCColors.COLOR_MAP[color_code]))
                    color_names.append(IRCColors.get_color_name(IRCColors.COLOR_MAP[color_code]))
                else:
                    pattern.append(int(color_code))
                    color_names.append(IRCColors.get_color_name(color_code.zfill(2)))
            
            # Kullanıcı tercihini kaydet
            self.user_color_prefs[nick] = pattern
            
            # Ornek goster
            example = IRCColors.rainbow("TUTKU FM", pattern)
            self.send_raw(f"PRIVMSG {target} :{example}")
            
            color_list = " → ".join(color_names)
            self.send_privmsg(target, f"Renk pattern'i ayarlandı: {color_list}", color_type="success")
            
        except Exception as e:
            self.send_privmsg(target, f"Renk ayarlama hatası: {str(e)}", color_type="error")
    
    def handle_theme_command(self, nick: str, args: List[str], target: str):
        """Tema değiştirme komutu"""
        if not args:
            themes = list(ThemeSystem.THEMES.keys())
            self.send_privmsg(target, f"Mevcut temalar: {', '.join(themes)}", color_type="info")
            return
        
        theme_name = args[0].lower()
        if theme_name in ThemeSystem.THEMES:
            self.current_theme = theme_name
            self.colors = ThemeSystem.apply_theme(theme_name)
            
            self.send_privmsg(target, f"'{theme_name}' teması uygulandı!", color_type="success")
            
            # Tema renklerini goster
            theme_colors = []
            for color_type, color_code in self.colors.items():
                color_name = IRCColors.get_color_name(color_code)
                colored_name = IRCColors.colorize(color_name, color_code)
                theme_colors.append(f"{color_type}:{colored_name}")
            
            self.send_privmsg(target, f"Renkler: {', '.join(theme_colors[:4])}", color_type="info")
        else:
            self.send_privmsg(target, f"'{theme_name}' teması bulunamadı!", color_type="error")
    
    def show_colors(self, nick: str, target: str):
        """Renkleri göster"""
        title = IRCColors.rainbow(" IRC Renk Kodları:", [4, 7, 8])
        self.send_raw(f"PRIVMSG {target} :{title}")
        
        colors_demo = [
            ("00", "Beyaz"), ("01", "Siyah"), ("02", "Koyu Mavi"),
            ("03", "Koyu Yesil"), ("04", "Kirmizi"), ("05", "Koyu Kirmizi"),
            ("06", "Mor"), ("07", "Turuncu"), ("08", "Sari"),
            ("09", "Acik Yesil"), ("10", "Cyan"), ("11", "Acik Cyan"),
            ("12", "Mavi"), ("13", "Acik Mor"), ("14", "Koyu Gri"),
            ("15", "Acik Gri")
        ]
        
        for code, name in colors_demo:
            demo_text = IRCColors.colorize(f" {code}:{name} ", code)
            self.send_raw(f"PRIVMSG {target} :{demo_text}")
            
        self.send_privmsg(target, "Kullanım: !anarenk 4 7 8 (kirmizi, turuncu, sari)", color_type="info")
    
    def handle_nick_register(self, nick: str, args: List[str], target: str):
        """Nick kaydını onaylama"""
        if not self.check_admin(nick):
            self.send_privmsg(target, " Bu komut icin admin yetkisi gerekiyor!", color_type="error")
            return
        
        if len(args) < 2:
            self.send_privmsg(target, "Kullanım: !nickkayit <nick> <sifre>", color_type="info")
            return
        
        target_nick, password = args[0], args[1]
        
        # NickServ'e kayıt komutu gonder
        self.send_raw(f"PRIVMSG NickServ :REGISTER {password} {target_nick}@tutkufm.com")
        
        # Basarılı mesaj
        self.send_privmsg(target, f" Nick kaydı onaylandı: {target_nick}", color_type="success")
        oper_channel = self.config.get('oper_channel', '#opers')
        self.send_privmsg(oper_channel, f" {nick}, {target_nick} nick kaydını onayladı!", color_type="info")
        
        self.log_action('NICK_KAYIT', f"{nick} -> {target_nick}")
    
    def handle_oper_application_approve(self, nick: str, args: List[str], target: str):
        """Oper başvurusunu onayla"""
        if not self.check_admin(nick):
            self.send_privmsg(target, " Bu komut icin admin yetkisi gerekiyor!", color_type="error")
            return
        
        if not args:
            self.send_privmsg(target, "Kullanım: !onaylandi <nick>", color_type="info")
            return
        
        app_nick = args[0]
        
        # Başvuruyu bul
        found_app = None
        for app_id, app in self.oper_applications.items():
            if app.get('nick', '').upper() == app_nick.upper() and app.get('status') == 'pending':
                found_app = app
                app_id_found = app_id
                break
        
        if not found_app:
            self.send_privmsg(target, f" {app_nick} icin bekleyen basvuru bulunamadı!", color_type="error")
            return
        
        # Başvuruyu onayla
        found_app['status'] = 'approved'
        found_app['approved_by'] = nick
        found_app['approved_at'] = datetime.now().isoformat()
        
        # Kullanıcıya ozel mesaj gonder
        self.send_privmsg(app_nick, f" Tebrikler! Oper basvurunuz {nick} tarafından onaylandı!", color_type="success")
        self.send_privmsg(app_nick, f" Detaylar: {found_app.get('name', '')} | {found_app.get('phone', '')}", color_type="info")
        
        # Kanalda duyur
        self.send_privmsg(target, f" {app_nick} oper basvurusu onaylandı!", color_type="success")
        oper_channel = self.config.get('oper_channel', '#opers')
        self.send_privmsg(oper_channel, f" YENI OPER: {app_nick} ({found_app.get('name', '')})", color_type="info")
        
        self.log_action('OPER_ONAY', f"{nick} -> {app_nick}")
    
    def handle_oper_application_reject(self, nick: str, args: List[str], target: str):
        """Oper başvurusunu reddet"""
        if not self.check_admin(nick):
            self.send_privmsg(target, " Bu komut icin admin yetkisi gerekiyor!", color_type="error")
            return
        
        if len(args) < 2:
            self.send_privmsg(target, "Kullanım: !reddedildi <nick> <sebep>", color_type="info")
            return
        
        app_nick, reason = args[0], ' '.join(args[1:])
        
        # Başvuruyu bul
        found_app = None
        for app_id, app in self.oper_applications.items():
            if app.get('nick', '').upper() == app_nick.upper() and app.get('status') == 'pending':
                found_app = app
                app_id_found = app_id
                break
        
        if not found_app:
            self.send_privmsg(target, f" {app_nick} icin bekleyen basvuru bulunamadı!", color_type="error")
            return
        
        # Başvuruyu reddet
        found_app['status'] = 'rejected'
        found_app['rejected_by'] = nick
        found_app['rejected_at'] = datetime.now().isoformat()
        found_app['rejected_reason'] = reason
        
        # Kullanıcıya ozel mesaj gonder
        self.send_privmsg(app_nick, f" Oper basvurunuz {nick} tarafından reddedildi.", color_type="error")
        self.send_privmsg(app_nick, f" Sebep: {reason}", color_type="info")
        
        # Kanalda duyur
        self.send_privmsg(target, f" {app_nick} oper basvurusu reddedildi: {reason}", color_type="warning")
        
        self.log_action('OPER_RED', f"{nick} -> {app_nick} - {reason}")
    
    def handle_oper_application_ban(self, nick: str, args: List[str], target: str):
        """Oper başvurusu yasağı ekle"""
        if not self.check_admin(nick):
            self.send_privmsg(target, " Bu komut icin admin yetkisi gerekiyor!", color_type="error")
            return
        
        if len(args) < 2:
            self.send_privmsg(target, "Kullanım: !basvuruyasak <nick> <sebep>", color_type="info")
            return
        
        banned_nick, reason = args[0], ' '.join(args[1:])
        
        # Yasağı kaydet
        self.oper_application_bans[banned_nick] = {
            'reason': reason,
            'banned_by': nick,
            'banned_at': datetime.now().isoformat()
        }
        
        # Bekleyen başvuruları reddet
        for app_id, app in self.oper_applications.items():
            if app.get('nick', '').upper() == banned_nick.upper() and app.get('status') == 'pending':
                app['status'] = 'rejected'
                app['rejected_by'] = nick
                app['rejected_at'] = datetime.now().isoformat()
                app['rejected_reason'] = f"Basvuru yasağı: {reason}"
        
        # Kanalda duyur
        self.send_privmsg(target, f" {banned_nick} icin oper basvuru yasağı eklendi: {reason}", color_type="warning")
        oper_channel = self.config.get('oper_channel', '#opers')
        self.send_privmsg(oper_channel, f" {banned_nick} artık oper basvurusu YAPAMAZ!", color_type="error")
        
        self.log_action('OPER_BAN', f"{nick} -> {banned_nick} - {reason}")
    
    def handle_oper_applications_list(self, nick: str, target: str):
        """Bekleyen oper başvurularını listele"""
        if not self.check_admin(nick):
            self.send_privmsg(target, " Bu komut icin admin yetkisi gerekiyor!", color_type="error")
            return
        
        pending_apps = [app for app in self.oper_applications.values() if app.get('status') == 'pending']
        
        if not pending_apps:
            self.send_privmsg(target, " Bekleyen oper basvurusu yok.", color_type="info")
            return
        
        self.send_privmsg(target, f" Bekleyen Oper Başvuruları ({len(pending_apps)}):", color_type="info")
        
        for app in pending_apps[:5]:
            self.send_privmsg(target, f"   {app.get('nick')} ({app.get('name')}) - Tel: {app.get('phone')}", color_type="info")
            self.send_privmsg(target, f"      {app.get('online_hours')} | IP: {app.get('ip', 'N/A')}", color_type="info")
        
        if len(pending_apps) > 5:
            self.send_privmsg(target, f"  ... ve {len(pending_apps) - 5} basvuru daha", color_type="info")
        
        self.send_privmsg(target, " Onay icin: !onaylandi <nick>", color_type="info")
        self.send_privmsg(target, " Red icin: !reddedildi <nick> sebep", color_type="info")
    
    def handle_ban_command(self, nick: str, cmd_type: str, args: List[str], target: str):
        """Ban komutları"""
        if not self.is_oper:
            self.send_privmsg(target, " Bot oper yetkisi almadı! Komut calıstırılamıyor.", color_type="error")
            return
        
        if len(args) < 2:
            self.send_privmsg(target, f"Kullanım: !{cmd_type} <ip/host> <sebep> [sure_dakika]", color_type="info")
            return
        
        ip_mask, reason = args[0], ' '.join(args[1:-1]) if len(args) > 2 else args[1]
        duration = int(args[-1]) if args[-1].isdigit() else 0
        
        # IP format kontrolu
        if not self.validate_ip_mask(ip_mask):
            self.send_privmsg(target, f" Gecersiz IP/hostmask: {ip_mask}", color_type="error")
            return
        
        # Komutu gonder
        if duration > 0:
            self.send_raw(f"{cmd_type.upper()} *@{ip_mask} {duration} :{reason} (IRC:{nick})")
            msg = f"{duration} dakika {cmd_type.upper()}"
        else:
            self.send_raw(f"{cmd_type.upper()} *@{ip_mask} :{reason} (IRC:{nick})")
            msg = f"Kalıcı {cmd_type.upper()}"
        
        self.send_privmsg(target, f" {msg} eklendi: {ip_mask}", color_type="success")
        self.log_action('BAN', f"{msg}: {ip_mask} - {reason}")
    
    def handle_sqline_command(self, nick: str, args: List[str], target: str):
        """SQLine komutları"""
        if not self.is_oper:
            self.send_privmsg(target, " Bot oper yetkisi almadı!", color_type="error")
            return
        
        if len(args) < 2:
            self.send_privmsg(target, "Kullanım: !sqline <add/del> <nick> <sebep> [sure_gun]", color_type="info")
            return
        
        action, target_nick = args[0].lower(), args[1]
        
        if action == 'add':
            if len(args) < 3:
                self.send_privmsg(target, "Kullanım: !sqline add <nick> <sebep> [sure_gun]", color_type="info")
                return
            
            reason = ' '.join(args[2:-1]) if len(args) > 3 else args[2]
            duration = int(args[-1]) if args[-1].isdigit() else 0
            
            if duration > 0:
                self.send_raw(f"SQLINE +{duration} {target_nick} :{reason} (IRC:{nick})")
                msg = f"{duration} gun SQLINE"
            else:
                self.send_raw(f"SQLINE +0 {target_nick} :{reason} (IRC:{nick})")
                msg = "Kalıcı SQLINE"
            
            self.send_privmsg(target, f" {msg} eklendi: {target_nick}", color_type="success")
            self.log_action('SQLINE', f"{msg}: {target_nick} - {reason}")
        
        elif action == 'del':
            self.send_raw(f"SQLINE -{target_nick}")
            self.send_privmsg(target, f" SQLINE silindi: {target_nick}", color_type="success")
            self.log_action('SQLINE_SIL', f"{target_nick}")
    
    def handle_spamfilter_command(self, nick: str, args: List[str], target: str):
        """Spamfilter komutları"""
        if not self.is_oper:
            self.send_privmsg(target, " Bot oper yetkisi almadı!", color_type="error")
            return
        
        if len(args) < 3:
            self.send_privmsg(target, "Kullanım: !spamfilter <add/del> <tur> <filtre> [aksiyon]", color_type="info")
            return
        
        action, filter_type, pattern = args[0].lower(), args[1].lower(), args[2]
        
        # Spamfilter ekle
        if action == 'add':
            if filter_type == 'normal':
                self.send_raw(f"SPAMFILTER add cpnN block - Yasak_Kelime: *{pattern}*")
            elif filter_type == 'nick':
                self.send_raw(f"SPAMFILTER add u block - Yasak_IDENT: ^({pattern}!.+@.+:.+)$")
            elif filter_type == 'ident':
                self.send_raw(f"SPAMFILTER add u block - Yasak_Nick: ^(.+!{pattern}@.+:.+)$")
            elif filter_type == 'ip':
                self.send_raw(f"SPAMFILTER add u gzline - Yasak_IP : ^(.+!.+@{pattern}:.+)$")
            
            self.send_privmsg(target, f" Spamfilter eklendi: {filter_type} - {pattern}", color_type="success")
            self.log_action('SPAMFILTER', f"{filter_type} - {pattern}")
        
        # Spamfilter sil
        elif action == 'del':
            if filter_type == 'normal':
                self.send_raw(f"SPAMFILTER del cpnN block - Yasak_Kelime: *{pattern}*")
            elif filter_type == 'nick':
                self.send_raw(f"SPAMFILTER del u block - Yasak_Nick: ^({pattern}!.+@.+:.+)$")
            elif filter_type == 'ident':
                self.send_raw(f"SPAMFILTER del u block - Yasak_IDENT: ^(.+!{pattern}@.+:.+)$")
            elif filter_type == 'ip':
                self.send_raw(f"SPAMFILTER del u gzline - Yasak_IP : ^(.+!.+@{pattern}:.+)$")
            
            self.send_privmsg(target, f" Spamfilter silindi: {filter_type} - {pattern}", color_type="success")
            self.log_action('SPAMFILTER_SIL', f"{filter_type} - {pattern}")
    
    def handle_radio_command(self, nick: str, args: List[str], target: str):
        """Radyo komutları"""
        if not args:
            self.show_radio_info(target)
            return
        
        subcmd = args[0].lower()
        
        if subcmd == 'info':
            self.show_radio_info(target)
        
        elif subcmd == 'dj':
            if len(args) < 2:
                self.send_privmsg(target, "Kullanım: !radio dj <dj_nick>", color_type="info")
                return
            dj_name = ' '.join(args[1:])
            self.send_privmsg(target, f" Yeni DJ: {dj_name}", color_type="info")
            radio_channel = self.config.get('radio_channel', '#mavifm')
            self.send_privmsg(radio_channel, f" Yeni DJ: {dj_name} ({nick})", color_type="info")
        
        elif subcmd == 'song':
            if len(args) < 2:
                self.send_privmsg(target, "Kullanım: !radio song <sarki_adi>", color_type="info")
                return
            song = ' '.join(args[1:])
            self.send_privmsg(target, f" Calan: {song}", color_type="info")
            radio_channel = self.config.get('radio_channel', '#mavifm')
            self.send_privmsg(radio_channel, f" Su an calıyor: {song}", color_type="info")
        
        elif subcmd == 'request':
            if len(args) < 3:
                self.send_privmsg(target, "Kullanım: !radio request <sanatcı> <sarki>", color_type="info")
                return
            artist, song = args[1], args[2]
            self.send_privmsg(target, f" {nick} istek yaptı: {artist} - {song}", color_type="info")
            radio_channel = self.config.get('radio_channel', '#mavifm')
            self.send_privmsg(radio_channel, f" Istek: {artist} - {song} ({nick})", color_type="info")
        
        elif subcmd == 'gift':
            if len(args) < 2:
                self.send_privmsg(target, "Kullanım: !radio gift <mesaj>", color_type="info")
                return
            message = ' '.join(args[1:])
            self.send_privmsg(target, f" {nick}: {message}", color_type="info")
            radio_channel = self.config.get('radio_channel', '#mavifm')
            self.send_privmsg(radio_channel, f" Armagan: {message} ({nick})", color_type="info")
    
    def handle_country_command(self, nick: str, args: List[str], target: str):
        """Ülke engelleme"""
        if not self.is_oper:
            self.send_privmsg(target, " Bot oper yetkisi almadı!", color_type="error")
            return
        
        if len(args) < 2:
            self.send_privmsg(target, "Kullanım: !country <add/del> <ulke_kodu>", color_type="info")
            return
        
        action, country = args[0].lower(), args[1].upper()
        
        if len(country) != 2:
            self.send_privmsg(target, " Ulke kodu 2 harf olmalı (TR, US, DE)", color_type="error")
            return
        
        if action == 'add':
            self.send_raw(f"GLINE + *{country}* 86400 :GuvenLik_Ulke_Engeli")
            self.send_privmsg(target, f" Ulke engellendi: {country}", color_type="success")
            self.log_action('ULKE_ENGEL', f"{country}")
        
        elif action == 'del':
            self.send_raw(f"GLINE - *{country}*")
            self.send_privmsg(target, f" Ulke engeli kaldırıldı: {country}", color_type="success")
            self.log_action('ULKE_ENGEL_KALDIR', f"{country}")
    
    def handle_as_command(self, nick: str, args: List[str], target: str):
        """AS engelleme"""
        if not self.is_oper:
            self.send_privmsg(target, " Bot oper yetkisi almadı!", color_type="error")
            return
        
        if len(args) < 2:
            self.send_privmsg(target, "Kullanım: !as <add/del> <as_no>", color_type="info")
            return
        
        action, as_no = args[0].lower(), args[1].upper()
        
        if not as_no.startswith('AS'):
            as_no = 'AS' + as_no
        
        if action == 'add':
            self.send_raw(f"GLINE + *!*@{as_no}* 86400 :GuvenLik_AS_Engeli")
            self.send_privmsg(target, f" AS engellendi: {as_no}", color_type="success")
            self.log_action('AS_ENGEL', f"{as_no}")
        
        elif action == 'del':
            self.send_raw(f"GLINE - *!*@{as_no}*")
            self.send_privmsg(target, f" AS engeli kaldırıldı: {as_no}", color_type="success")
            self.log_action('AS_ENGEL_KALDIR', f"{as_no}")
    
    def handle_ticket_command(self, nick: str, args: List[str], target: str):
        """Ticket sistemi - SADECE KANALA GÖNDER"""
        if not args:
            self.send_privmsg(target, " Ticket Komutları: !ticket list, !ticket view <id>, !ticket close <id>", color_type="info")
            return
        
        subcmd = args[0].lower()
        
        if subcmd == 'list':
            if not self.tickets:
                self.send_privmsg(target, " Aktif ticket yok.", color_type="info")
            else:
                self.send_privmsg(target, " Aktif Ticketlar:", color_type="info")
                for ticket_id, ticket in self.tickets.items():
                    if ticket.get('status') == 'open':
                        self.send_privmsg(target, f"  #{ticket_id}: {ticket.get('subject', 'Konu Yok')} - {ticket.get('nick', 'Anonim')}", color_type="info")
        
        elif subcmd == 'create':
            if len(args) < 2:
                self.send_privmsg(target, "Kullanım: !ticket create <konu>", color_type="info")
                return
            subject = ' '.join(args[1:])
            
            # Yeni ticket oluştur
            ticket_id = self.next_ticket_id
            self.tickets[ticket_id] = {
                'id': ticket_id,
                'nick': nick,
                'subject': subject,
                'status': 'open',
                'created': datetime.now().isoformat(),
                'ip': 'IRC'
            }
            self.next_ticket_id += 1
            
            # ⚡ DEĞİŞİKLİK: SADECE OPER KANALINA GÖNDER
            oper_channel = self.config.get('oper_channel', '#opers')
            self.send_privmsg(target, f"  Ticket oluşturuldu: #{ticket_id}", color_type="success")
            
            # Renkli ticket bildirimi
            safe_subject = self._replace_turkish_chars(subject)
            title_msg = IRCColors.colorize(f"🎫 YENI TICKET #{ticket_id}", "07") + " " + IRCColors.colorize(f"Konu: {safe_subject}", "12")
            self.send_raw(f"PRIVMSG {oper_channel} :{title_msg}")
            
            sender_msg = IRCColors.colorize("Gönderen:", "03") + " " + IRCColors.colorize(f"{nick}", "15") + " " + IRCColors.colorize("| Kaynak:", "03") + " " + IRCColors.colorize("IRC", "15")
            self.send_raw(f"PRIVMSG {oper_channel} :{sender_msg}")
            
            management_msg = IRCColors.colorize("Yönetim:", "04") + " " + IRCColors.colorize(f"!ticket view {ticket_id}", "08") + " " + IRCColors.colorize("|", "14") + " " + IRCColors.colorize(f"!ticket close {ticket_id}", "08")
            self.send_raw(f"PRIVMSG {oper_channel} :{management_msg}")
        
        elif subcmd == 'view':
            if len(args) < 2:
                self.send_privmsg(target, "Kullanım: !ticket view <id>", color_type="info")
                return
            
            try:
                ticket_id = int(args[1])
                if ticket_id in self.tickets:
                    ticket = self.tickets[ticket_id]
                    self.send_privmsg(target, f" Ticket #{ticket_id}:", color_type="info")
                    self.send_privmsg(target, f"   {ticket.get('nick', 'Anonim')}", color_type="info")
                    self.send_privmsg(target, f"   {ticket.get('subject', 'Konu Yok')}", color_type="info")
                    self.send_privmsg(target, f"   {ticket.get('created', 'Bilinmiyor')}", color_type="info")
                    self.send_privmsg(target, f"   {ticket.get('status', 'open').upper()}", color_type="info")
                else:
                    self.send_privmsg(target, f" Ticket #{ticket_id} bulunamadı.", color_type="error")
            except ValueError:
                self.send_privmsg(target, " Gecersiz ticket ID.", color_type="error")
        
        elif subcmd == 'close':
            if len(args) < 2:
                self.send_privmsg(target, "Kullanım: !ticket close <id>", color_type="info")
                return
            
            try:
                ticket_id = int(args[1])
                if ticket_id in self.tickets:
                    self.tickets[ticket_id]['status'] = 'closed'
                    self.tickets[ticket_id]['closed_by'] = nick
                    self.tickets[ticket_id]['closed_at'] = datetime.now().isoformat()
                    
                    # ⚡ DEĞİŞİKLİK: SADECE OPER KANALINA GÖNDER
                    oper_channel = self.config.get('oper_channel', '#opers')
                    self.send_privmsg(target, f"  Ticket #{ticket_id} kapatıldı.", color_type="success")
                    
                    # Renkli kapatma bildirimi
                    closed_msg = IRCColors.colorize(f"✅ Ticket #{ticket_id}", "09") + " " + IRCColors.colorize(f"kapatıldı.", "15") + " " + IRCColors.colorize(f"({nick})", "03")
                    self.send_raw(f"PRIVMSG {oper_channel} :{closed_msg}")
                    
                    subject = self.tickets[ticket_id].get('subject', '')
                    if subject:
                        subject_msg = IRCColors.colorize("Konu:", "03") + " " + IRCColors.colorize(f"{subject}", "15")
                        self.send_raw(f"PRIVMSG {oper_channel} :{subject_msg}")
                else:
                    self.send_privmsg(target, f" Ticket #{ticket_id} bulunamadı.", color_type="error")
            except ValueError:
                self.send_privmsg(target, " Gecersiz ticket ID.", color_type="error")
    
    def handle_points_command(self, nick: str, args: List[str], target: str):
        """Puan sistemi"""
        if not args:
            self.send_privmsg(target, " Puan Sistemi: !points top, !points add <nick> <puan>, !points check [nick]", color_type="info")
            return
        
        subcmd = args[0].lower()
        
        if subcmd == 'top':
            self.send_privmsg(target, " Top 10 Eglence Puanı:", color_type="info")
            self.send_privmsg(target, "1. SADO: 10,000 puan", color_type="info")
            self.send_privmsg(target, "2. KALPSIZ: 8,500 puan", color_type="info")
            self.send_privmsg(target, "3. NS-HELP: 7,200 puan", color_type="info")
            self.send_privmsg(target, "4. Q-CYCLE: 6,800 puan", color_type="info")
            self.send_privmsg(target, "5. CS-HELP: 5,500 puan", color_type="info")
        
        elif subcmd == 'add' and self.check_admin(nick):
            if len(args) < 3:
                self.send_privmsg(target, "Kullanım: !points add <nick> <puan>", color_type="info")
                return
            target_nick, points = args[1], args[2]
            
            if target_nick not in self.user_points:
                self.user_points[target_nick] = 0
            
            try:
                points_int = int(points)
                self.user_points[target_nick] += points_int
                self.send_privmsg(target, f" {target_nick}'e {points} puan eklendi. Toplam: {self.user_points[target_nick]}", color_type="success")
            except ValueError:
                self.send_privmsg(target, " Gecersiz puan degeri.", color_type="error")
        
        elif subcmd == 'check':
            check_nick = args[1] if len(args) > 1 else nick
            
            if check_nick in self.user_points:
                self.send_privmsg(target, f" {check_nick}: {self.user_points[check_nick]} puan", color_type="info")
            else:
                self.send_privmsg(target, f" {check_nick}: 0 puan", color_type="info")
    
    def handle_join_command(self, nick: str, args: List[str], target: str):
        """Kanal katılma komutu"""
        if not args:
            self.send_privmsg(target, "Kullanım: !join <#kanal>", color_type="info")
            return
        
        channel = args[0]
        if not channel.startswith('#'):
            channel = '#' + channel
        
        # Sadece izinli kanallara katıl
        channels = self.config.get('channels', [])
        if channel not in channels:
            self.send_privmsg(target, f" {channel} kanalına katılma izniniz yok!", color_type="error")
            return
        
        self.send_raw(f"JOIN {channel}")
        self.send_privmsg(target, f" {channel} kanalına katıldım", color_type="success")
    
    def handle_part_command(self, nick: str, args: List[str], target: str):
        """Kanal ayrılma komutu"""
        if not args:
            self.send_raw(f"PART {target}")
            self.send_privmsg(target, " Kanalı terk ettim", color_type="info")
            return
        
        channel = args[0]
        if not channel.startswith('#'):
            channel = '#' + channel
        
        self.send_raw(f"PART {channel}")
        self.send_privmsg(target, f" {channel} kanalını terk ettim", color_type="info")
    
    def show_radio_info(self, target: str):
        """Radyo bilgilerini göster"""
        current_time = datetime.now().strftime("%H:%M")
        
        title = IRCColors.rainbow(" TUTKU FM RADYO - Canlı Yayın", [4, 7, 8])
        self.send_raw(f"PRIVMSG {target} :{title}")
        
        self.send_privmsg(target, " DJ: SADO", color_type="info")
        self.send_privmsg(target, " Calan: En Yeni Sarkılar", color_type="info")
        self.send_privmsg(target, " Dinleyici: 125 aktif", color_type="info")
        self.send_privmsg(target, " Istek Sistemi: ACIK", color_type="success")
        self.send_privmsg(target, " Armagan Sistemi: ACIK", color_type="success")
        self.send_privmsg(target, f" Saat: {current_time}", color_type="info")
        self.send_privmsg(target, " Dinle: https://tutkufm.com", color_type="info")
    
    def show_help(self, nick: str, target: str):
        """Yardım menüsü"""
        title = IRCColors.rainbow(f" {nick}, TUTKU XLine Bot Komutları (v{self.config['version']}):", [4, 7, 8])
        self.send_raw(f"PRIVMSG {target} :{title}")
        
        if self.check_admin(nick):
           admin_title = IRCColors.colorize(" ADMIN KOMUTLARI:", "04")
           self.send_raw(f"PRIVMSG {target} :{admin_title}")
           self.send_privmsg(target, " !onaylandi !reddedildi !basvuruyasak !nickkayit !basvurular", color_type="admin")
           self.send_privmsg(target, " !forceoper !checkoper !xline !sqline !spamfilter", color_type="admin")
           self.send_privmsg(target, " !country !as !join !part", color_type="admin")       
 
        self.send_privmsg(target, " RADYO: !radio info/dj/song/request/gift", color_type="info")
        self.send_privmsg(target, " TICKET: !ticket list/create/view/close", color_type="info")
        self.send_privmsg(target, " PUAN: !points top/add/check", color_type="info")
        self.send_privmsg(target, " RENK: !anarenk !tema !renkler", color_type="highlight")
        self.send_privmsg(target, " SIKAYET: Web panelden XLine ve sikayet bildirimi", color_type="warning")
        self.send_privmsg(target, f" Web Panel: {self.config.get('web_domain', 'localhost')}", color_type="success")
        self.send_privmsg(target, f" Bildirimler: {self.config.get('oper_channel', '#opers')} kanalına gonderilir", color_type="info")
    
    def show_stats(self, nick: str, target: str):
        """Bot istatistikleri"""
        uptime = self.get_uptime()
        pending_apps = sum(1 for app in self.oper_applications.values() if app.get('status') == 'pending')        
        title = IRCColors.rainbow(f" {self.config['nickname']} Istatistikleri:", [4, 7, 8])
        self.send_raw(f"PRIVMSG {target} :{title}")        
        self.send_privmsg(target, f" Calisma: {uptime}", color_type="info")
        self.send_privmsg(target, f" Durum: {'OPER' if self.is_oper else 'USER'}", color_type="info")
        self.send_privmsg(target, f" Nick Auth: {'EVET' if self.authenticated else 'HAYIR'}", color_type="info")
        self.send_privmsg(target, f" Versiyon: v{self.config['version']}", color_type="info")
        self.send_privmsg(target, f" Sahip: {self.config.get('owner', 'Bilinmiyor')}", color_type="info")
        self.send_privmsg(target, f" Kanallar: {len(self.config.get('channels', []))}", color_type="info")
        self.send_privmsg(target, f" Ticketlar: {len(self.tickets)}", color_type="info")
        self.send_privmsg(target, f" Oper Başvuruları: {pending_apps} beklemede", color_type="info")
        self.send_privmsg(target, f" Web Panel: {self.config.get('web_domain', 'localhost')}", color_type="success")
    
    def handle_private_message(self, nick: str, message: str):
        """Özel mesajları işler"""
        if self.config.get('debug_mode', False):
            print(f" PM: {nick}: {message}")
        
        command_prefix = self.config.get('command_prefix', '!')
        if message.startswith(command_prefix):
            cmd = message[len(command_prefix):].split()[0].lower()
            
            if cmd == 'auth':
                self.send_notice(nick, " Kimlik dogrulama otomatik yapıldı.", color_type="info")
            
            elif cmd == 'register':
                self.send_notice(nick, f" Kayıt icin web paneli kullanın: {self.config.get('web_domain', 'localhost')}", color_type="info")
            
            elif cmd == 'stats':
                self.show_stats(nick, nick)
            
            elif cmd == 'help':
                self.send_notice(nick, " Komutlar icin #help kanalına bakın veya !help yazın.", color_type="info")
            
            elif cmd == 'ticket':
                self.send_notice(nick, " Ticket olusturmak icin: !ticket create <konu>", color_type="info")
            
            elif cmd == 'radio':
                self.send_notice(nick, " Radyo isteği icin web paneli kullanın veya #mavifm kanalında !radio request yazın.", color_type="info")
            
            elif cmd == 'basvuru':
                # Oper başvurusu durumu sorgulama
                for app_id, app in self.oper_applications.items():
                    if app.get('nick', '').upper() == nick.upper():
                        status = app.get('status', 'pending')
                        if status == 'pending':
                            self.send_notice(nick, " Basvurunuz henuz inceleniyor. Lutfen bekleyin.", color_type="info")
                        elif status == 'approved':
                            approved_by = app.get('approved_by', 'Bilinmiyor')
                            approved_at = app.get('approved_at', 'Bilinmiyor')
                            self.send_notice(nick, f" Basvurunuz onaylandı! Onaylayan: {approved_by}, Tarih: {approved_at}", color_type="success")
                        elif status == 'rejected':
                            reason = app.get('rejected_reason', 'Sebep belirtilmemis')
                            self.send_notice(nick, f" Basvurunuz reddedildi. Sebep: {reason}", color_type="error")
                        return
                self.send_notice(nick, " Kayıtlı basvurunuz bulunamadı.", color_type="warning")
        
        else:
            welcome = IRCColors.rainbow(f"Merhaba {nick}!", [4, 7, 8])
            self.send_raw(f"NOTICE {nick} :{welcome}")
            self.send_notice(nick, f" Komutlar icin !help yazın. Web Panel: {self.config.get('web_domain', 'localhost')}", color_type="info")
    
    def check_admin(self, nick: str) -> bool:
        """Admin kontrolü"""
        admin_nicks = self.config.get('admin_nicks', [])
        return nick.upper() in [n.upper() for n in admin_nicks]
    
    def validate_ip_mask(self, ip_mask: str) -> bool:
        """IP mask validasyonu"""
        patterns = [
            r'^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$',
            r'^\d{1,3}\.\d{1,3}\.\d{1,3}\.\*$',
            r'^\d{1,3}\.\d{1,3}\.\*\.\*$',
            r'^\d{1,3}\.\*\.\*\.\*$',
        ]
        
        for pattern in patterns:
            if re.match(pattern, ip_mask):
                return True
        
        return False
    
    def get_uptime(self) -> str:
        """Çalışma süresi"""
        uptime = int(time.time() - self.start_time)
        
        if uptime < 60:
            return f"{uptime} saniye"
        elif uptime < 3600:
            minutes = uptime // 60
            seconds = uptime % 60
            return f"{minutes} dakika {seconds} saniye"
        elif uptime < 86400:
            hours = uptime // 3600
            minutes = (uptime % 3600) // 60
            return f"{hours} saat {minutes} dakika"
        else:
            days = uptime // 86400
            hours = (uptime % 86400) // 3600
            return f"{days} gun {hours} saat"
    
    def parse_line(self, line: str):
        """IRC satırını parse eder"""
        line = line.strip()
        if not line:
            return
        
        # PING/PONG
        if line.startswith('PING'):
            self.send_raw(line.replace('PING', 'PONG'))
            if self.config.get('debug_mode', False):
                print(" PING/PONG")
            return
        
        if self.config.get('debug_mode', False):
            print(f" {line}")
        
        # WHO yanıtları
        if '352' in line:
            self.handle_who_response(line)
            return
        
        # PRIVMSG
        if 'PRIVMSG' in line:
            try:
                parts = line.split(' ', 3)
                if len(parts) >= 4:
                    sender = parts[0][1:]  # :Nick!user@host
                    msg_type = parts[1]
                    target = parts[2]
                    message = parts[3][1:]  # :message
                    
                    if msg_type == 'PRIVMSG':
                        self.handle_privmsg(sender, target, message)
                        return
            except:
                if self.config.get('debug_mode', False):
                    print(" PRIVMSG parse hatası")
        
        # Diğer sunucu mesajları
        self.handle_server_message(line)
    
    def send_ping(self):
        """PING gönder (keepalive)"""
        if self.irc_socket:
            try:
                self.send_raw(f"PING :{int(time.time())}")
            except:
                pass
    
    def run(self):
        """Botu çalıştır"""
        banner = """
        ╔══════════════════════════════════════════════════════════╗
        ║                                                          ║
        ║   Tutku XLine Bot v3.3 - Turkce Karakter Sorunu      ║
        ║   Duzenlenmiş Versiyon                                  ║
        ║                                                          ║
        ║   Tur karakterler ASCII'ye cevriliyor                   ║
        ║   Renk Sistemi: !anarenk !tema !renkler                 ║
        ║   Developer: Sado                                       ║
        ║   https://tutku.jetcozum.xyz                           ║
        ║                                                          ║
        ╚══════════════════════════════════════════════════════════╝
        """
        
        print(banner)
        print("=" * 70)
        print(" TUTKU XLine BOT Baslatılıyor...")
        print("=" * 70)
        print(f" {datetime.now().strftime('%d.%m.%Y %H:%M:%S')}")
        print(f"  Bot: {self.config['nickname']} v{self.config['version']}")
        print(f"  Sahip: {self.config.get('owner', 'Bilinmiyor')}")
        print(f"  Renk Sistemi: AKTIF")
        print(f"  Temalar: {', '.join(ThemeSystem.THEMES.keys())}")
        print(f"  IRC: {self.config['server']}:{self.config['port']}")
        print(f"  Web Panel: http://{self.config.get('web_host', '0.0.0.0')}:{self.config.get('web_port', 8080)}")
        print("=" * 70)
        
        # Web paneli baslat
        print("  Web panel baslatılıyor...")
        if not self.start_web_server():
            print("  Web panel baslatılamadı, sadece IRC devam edecek")
        else:
            print("  Web panel baslatıldı!")
        
        # Baslangıc zamanı
        self.start_time = time.time()
        last_ping = time.time()
        last_oper_check = time.time()
        
        # Ana dongu
        while self.running:
            try:
                # Baglantı yoksa yeniden baglan
                if not self.irc_socket:
                    self.connection_attempts += 1
                    
                    if self.connection_attempts > self.max_connection_attempts:
                        print(f"  Maksimum baglantı denemesi aşıldı ({self.max_connection_attempts})")
                        print("  60 saniye bekleniyor...")
                        time.sleep(60)
                        self.connection_attempts = 0
                        continue
                    
                    print(f"  Yeniden baglanılıyor... Deneme {self.connection_attempts}/{self.max_connection_attempts}")
                    
                    if not self.connect_irc():
                        print(f"  {self.connection_delay}s bekleniyor...")
                        time.sleep(self.connection_delay)
                        continue
                    
                    # Hosgeldin mesajlarını bekle
                    if not self.wait_for_welcome():
                        print("  Hosgeldin mesajı alınamadı")
                        self.irc_socket = None
                        time.sleep(self.connection_delay)
                        continue
                    
                    # Hemen identify ve OPER girişi yap
                    print("  Hemen identify ve OPER girişi yapılıyor...")
                    self.identify_and_oper()
                    
                    # Kanallara katıl (TEKRARLI GİRİŞ ÖNLENDİ)
                    self.join_channels()
                    
                    # Basarılı baglantı
                    self.connection_attempts = 0
                    print("  Baglantı ve login işlemi tamamlandı!")
                
                # Ping gonder (keepalive)
                current_time = time.time()
                ping_interval = self.config.get('ping_interval', 120)
                if current_time - last_ping > ping_interval:
                    self.send_ping()
                    last_ping = current_time
                
                # OPER durumunu periyodik kontrol et (SADECE 1 KEZ)
                if current_time - last_oper_check > 30 and not self.is_oper:
                    print("  OPER durumu kontrol ediliyor...")
                    self.check_oper_status()
                    
                    # Hala OPER değilse tekrar dene
                    if not self.is_oper and self.oper_retry_count < self.max_oper_retries:
                        self.oper_retry_count += 1
                        print(f"  OPER tekrar deneniyor... ({self.oper_retry_count}/{self.max_oper_retries})")
                        oper_nick = self.config.get('oper_nick')
                        oper_pass = self.config.get('oper_pass')
                        if oper_nick and oper_pass:
                            self.send_raw(f"OPER {oper_nick} {oper_pass}")
                    
                    last_oper_check = current_time
                
                #  Periyodik temizlik (her 1 saatte bir)
                if current_time - self.last_cleanup > self.backup_interval:
                    self.cleanup_old_tickets()
                    self.backup_data()
                    self.last_cleanup = current_time
                    print("  Periyodik temizlik yapıldı")
                
                # Veri al
                try:
                    data = self.irc_socket.recv(4096).decode('utf-8', errors='ignore')
                except socket.timeout:
                    continue
                except ConnectionResetError:
                    print("  Baglantı resetlendi!")
                    self.irc_socket = None
                    continue
                except:
                    data = ''
                
                if not data:
                    print("  Baglantı koptu!")
                    self.irc_socket = None
                    reconnect_delay = self.config.get('reconnect_delay', 5)
                    time.sleep(reconnect_delay)
                    continue
                
                # Satırları işle
                for line in data.split('\r\n'):
                    if line.strip():
                        self.parse_line(line)
                
            except KeyboardInterrupt:
                print("\n  Bot durduruluyor...")
                self.running = False
                break
            
            except Exception as e:
                print(f"  Ana dongu hatası: {e}")
                if self.config.get('debug_mode', False):
                    traceback.print_exc()
                time.sleep(2)
        
        # Temizlik
        if self.irc_socket:
            try:
                self.send_raw("QUIT :TutkuFM Bot durduruluyor")
                self.irc_socket.close()
            except:
                pass
        
        if self.web_server:
            try:
                self.web_server.shutdown()
            except:
                pass
        
        # Son yedekleme
        self.backup_data()
        
        print("  Bot durduruldu. Cıkıs yapılıyor...")
        print(f"  Toplam calısma suresi: {self.get_uptime()}")

def main():
    """Ana fonksiyon"""
    try:
        bot = TutkuBot()
        bot.run()
    except Exception as e:
        print(f"  Kritik hata: {e}")
        traceback.print_exc()
        sys.exit(1)

if __name__ == "__main__":
    main()