import sys, os
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
import unittest
from datetime import date, datetime
from optrabot import crud, models
from optrabot.tradehelper import TradeHelper
from optrabot.database import get_db_engine
from optrabot.tradestatus import TradeStatus
from optrabot.broker.order import OrderAction
from sqlalchemy.orm import Session

from testtools import *

class TradeHelperTests(unittest.TestCase):
	
	def test_getTradeIdFromOrderRef(self):
		test_orderRef = ''
		tradeId = TradeHelper.getTradeIdFromOrderRef(test_orderRef)
		self.assertEquals(tradeId, 0)
		test_orderRef = 'OTB (7): 0DTEIronFly Take Profit'
		tradeId = TradeHelper.getTradeIdFromOrderRef(test_orderRef)
		self.assertEquals(tradeId, 7)
		test_orderRef = 'OTB (13): 0DTEIronFly Open'
		tradeId = TradeHelper.getTradeIdFromOrderRef(test_orderRef)
		self.assertEquals(tradeId, 13)

	def test_isTransactionsComplete(self):
		with Session(get_test_db_engine()) as session:
			trade = crud.getTrade(session,21)
			result = TradeHelper.isTransactionsComplete(trade)
			self.assertEquals(result, True)
	
	def test_updateTrade(self):
		with Session(get_test_db_engine()) as session:
			trade = crud.getTrade(session,21)
			result = TradeHelper.updateTrade(trade)
			self.assertEquals(trade.status,'CLOSED')
			self.assertEquals(round(trade.realizedPNL, 2), round(-36.549350000000004, 2))
	
	def test_updateTrade2(self):
		with Session(get_test_db_engine()) as session:
			trade = crud.getTrade(session,25)
			trade.status = TradeStatus.EXPIRED
			result = TradeHelper.updateTrade(trade)
			self.assertEquals(trade.status,TradeStatus.EXPIRED)
			self.assertEquals(trade.realizedPNL,-60)
	
	def test_updateTrade_expired_creates_closing_transactions(self):
		"""
		OTB-262: Test that expired trades get closing transactions created
		and realizedPNL is calculated correctly.
		
		Scenario: Iron Condor opened, expires worthless (all legs OTM)
		Expected:
		- Closing transactions created at $0 for all legs
		- realizedPNL calculated (credit received - fees)
		- Status remains EXPIRED
		"""
		with Session(get_test_db_engine()) as session:
			# Create a test trade with EXPIRED status
			trade = models.Trade(
				account='TEST123',
				symbol='SPX',
				strategy='Iron Condor',
				status=TradeStatus.EXPIRED
			)
			session.add(trade)
			session.flush()
			
			# Add opening transactions for Iron Condor
			# Buy Call @6945, Sell Call @6935, Sell Put @6790, Buy Put @6780
			# Credit received: (0.25 - 0.25) + (1.15 - 1.0) = 0.15
			transactions = [
				models.Transaction(
					tradeid=trade.id, id=1, type=OrderAction.BUY, sectype='C',
					strike=6945.0, expiration=date.today(), contracts=1, price=0.25,
					fee=0.0, commission=1.55, timestamp=datetime.now()
				),
				models.Transaction(
					tradeid=trade.id, id=2, type=OrderAction.SELL, sectype='C',
					strike=6935.0, expiration=date.today(), contracts=1, price=0.25,
					fee=0.0, commission=1.55, timestamp=datetime.now()
				),
				models.Transaction(
					tradeid=trade.id, id=3, type=OrderAction.SELL, sectype='P',
					strike=6790.0, expiration=date.today(), contracts=1, price=1.15,
					fee=0.0, commission=1.64, timestamp=datetime.now()
				),
				models.Transaction(
					tradeid=trade.id, id=4, type=OrderAction.BUY, sectype='P',
					strike=6780.0, expiration=date.today(), contracts=1, price=1.0,
					fee=0.0, commission=1.64, timestamp=datetime.now()
				),
			]
			for tx in transactions:
				session.add(tx)
			session.commit()
			
			# Reload trade to get transactions
			trade = crud.getTrade(session, trade.id)
			
			# Verify initial state: 4 opening transactions
			self.assertEqual(len(trade.transactions), 4)
			
			# Call updateTrade with session - should create closing transactions
			TradeHelper.updateTrade(trade, session)
			
			# Commit changes (updateTrade doesn't commit when session is provided)
			session.commit()
			
			# OTB-262: Must reload trade from DB to see new transactions
			# session.expire() is not enough due to SQLAlchemy relationship caching
			trade = crud.getTrade(session, trade.id)
			
			# Verify: 8 transactions total (4 opening + 4 closing)
			self.assertEqual(len(trade.transactions), 8)
			
			# Verify: realizedPNL is calculated (should be credit - fees)
			# Credit: 0.15 * 100 = 15.0
			# Fees: (1.55 + 1.55 + 1.64 + 1.64) = 6.38
			# P&L: 15.0 - 6.38 = 8.62
			expected_pnl = round((0.15 * 100) - 6.38, 2)
			self.assertEqual(trade.realizedPNL, expected_pnl)
			
			# Verify: Status remains EXPIRED
			self.assertEqual(trade.status, TradeStatus.EXPIRED)