"""File watching and processing"""

import os
import sys
from typing import Optional

from brokers.base_broker import BaseBroker
from processors.order_processor import OrderProcessor
from utils.file_utils import FileUtils
from utils.logger import TradingLogger
from config.config import Config

class FileProcessor:
    """Handles file watching and processing"""
    
    def __init__(self, client_code: str, broker: BaseBroker, 
                 symbol_properties: dict, global_limits: dict,
                 watch_folder: str, processed_folder: str, config: Config):
        self.client_code = client_code
        self.broker = broker
        self.symbol_properties = symbol_properties
        self.global_limits = global_limits
        self.watch_folder = watch_folder
        self.processed_folder = processed_folder
        self.config = config
        self.logger = TradingLogger(client_code)
        
        self.order_processor = OrderProcessor(broker, client_code, symbol_properties, config)
        
        FileUtils.ensure_directory(self.processed_folder)
        
        self.logger.info(f"Initialized processor for client: {broker.client_id}")
        self.logger.info(f"Symbol Properties: {self.symbol_properties}")
        self.logger.info(f"Global Limits: {self.global_limits}")
    
    def parse_file_info(self, file_path: str) -> Optional[dict]:
        """Parse filename to extract order details"""
        try:
            file_name = os.path.basename(file_path)
            parts = file_name.split('__')
            
            if len(parts) < 6:
                self.logger.error(f"Invalid file format: {file_name}")
                return None
            
            return {
                'time': parts[0].replace(':', '-'),
                'symbol': parts[1],
                'action': parts[3],
                'no_lots': int(parts[4]),
                'notes': parts[5]
            }
        except Exception as e:
            self.logger.error(f"Failed to parse file {file_path}: {e}")
            return None
    
    def process_files(self) -> None:
        """Main processing loop"""
        if not self.broker.is_logged_in:
            if not self.broker.login():
                self.logger.error("Failed to login, exiting")
                sys.exit(1)
        
        max_profit = self.global_limits.get('max_profit_target', 0)
        max_loss = self.global_limits.get('max_loss_limit', 0)
        
        if self.broker.close_all_positions(max_profit, max_loss, self.broker.dynamic_profit_enabled):
            self.logger.info("Stop limits reached, exiting")
            sys.exit(0)
        
        if not os.path.exists(self.watch_folder):
            self.logger.warning(f"Watch folder not found: {self.watch_folder}")
            return
        
        runtime_settings = self.config.get_runtime_settings()
        allowed_extensions = runtime_settings.get('file_extensions', ['.txt', '.ord'])
        
        processed_count = 0
        
        for file_name in sorted(os.listdir(self.watch_folder)):
            if not self._is_valid_file(file_name, allowed_extensions):
                continue
            
            full_path = os.path.join(self.watch_folder, file_name)
            
            if self._process_single_file(full_path):
                self._replicate_file(file_name)
                processed_count += 1
        
        if processed_count > 0:
            self.logger.info(f"Processed {processed_count} new file(s)")
        
        self.order_processor.process_profit_orders()
    
    def _is_valid_file(self, file_name: str, allowed_extensions: list) -> bool:
        """Check if file should be processed"""
        source_path = os.path.join(self.watch_folder, file_name)
        target_path = os.path.join(self.processed_folder, file_name)
        
        if os.path.isdir(source_path) or os.path.exists(target_path):
            return False
        
        if not any(file_name.endswith(ext) for ext in allowed_extensions):
            return False
        
        return True
    
    def _replicate_file(self, file_name: str) -> None:
        """Copy processed file to client folder"""
        src = os.path.join(self.watch_folder, file_name)
        dst = os.path.join(self.processed_folder, file_name)
        
        try:
            FileUtils.copy_file_with_permissions(src, dst)
            self.logger.debug(f"Replicated file: {file_name}")
        except Exception as e:
            self.logger.error(f"Failed to replicate file {file_name}: {e}")
    
    def _process_single_file(self, file_path: str) -> bool:
        """Process individual order file"""
        info = self.parse_file_info(file_path)
        if not info:
            return False
        
        base_symbol = None
        for sym in self.symbol_properties:
            if info['symbol'].startswith(sym):
                base_symbol = sym
                break
        
        if not base_symbol:
            self.logger.error(f"Unrecognized symbol: {info['symbol']}")
            return False
        
        props = self.symbol_properties[base_symbol]
        if not props.get('enabled', False):
            self.logger.info(f"Trading disabled for symbol: {base_symbol}")
            return False
        
        quantity = self.order_processor.calculate_quantity(base_symbol, info['no_lots'])
        exchange = props.get('exchange')
        expiry = props.get('expiry')
        
        remarks = f"test__{info['time']}__{info['no_lots']}_{info['notes']}"
        
        self.logger.info(f"Placing order: {info['symbol']} - Qty: {quantity}, Action: {info['action']}")
        
        success = self.order_processor.place_order_with_split(
            symbol=base_symbol,
            action=info['action'],
            quantity=quantity,
            exchange=exchange,
            expiry=expiry,
            remarks=remarks
        )
        
        if success:
            self.logger.success(f"Order placed successfully: {info['symbol']}")
        else:
            self.logger.error(f"Failed to place order: {info['symbol']}")
        
        return success