from django.core.management.base import BaseCommand
from django.contrib.auth import get_user_model
from rest_framework.test import APIClient
from apps.business.distributor.models import (
    DistributorTransferHistory, DistributorTransferRequest, DistributorTransferTerms,
    DistributorRewardOwnershipLedger, DistributorOwnershipPeriod
)
from apps.business.products.models import Product
from apps.business.distributor.services.distributor_service import create_distributor_id
from decimal import Decimal
import uuid
from django.utils import timezone

User = get_user_model()


class Command(BaseCommand):
    help = 'Comprehensive transfer feature test with pre/post transfer benefit verification'

    def handle(self, *args, **options):
        print("=" * 100)
        print("COMPREHENSIVE TRANSFER TEST: Pre/Post Benefit Verification")
        print("=" * 100)

        # Clean slate
        DistributorTransferHistory.objects.all().delete()
        DistributorTransferRequest.objects.all().delete()
        print("\n[SETUP] Cleaned transfer data")

        try:
            # Test scenario 1: PowerStream ID with pre-transfer bonuses
            print("\n" + "=" * 100)
            print("TEST SCENARIO 1: PowerStream-Active ID with Pre-Transfer Powerstream Bonuses")
            print("=" * 100)

            sfx1 = uuid.uuid4().hex[:8]
            ps_old_owner = User.objects.create_user(
                mobile=f'91{sfx1}01', email=f'ps_old_{sfx1}@test.com', password='x12345',
                first_name='PS_Old', last_name='Owner'
            )
            # Set proper referral code after creation
            ps_old_owner.referral_code = f'PSOLD{sfx1.upper()}'[:16]
            ps_old_owner.save()
            
            ps_new_owner = User.objects.create_user(
                mobile=f'91{sfx1}02', email=f'ps_new_{sfx1}@test.com', password='x12345',
                first_name='PS_New', last_name='Owner'
            )
            ps_new_owner.referral_code = f'PSNEW{sfx1.upper()}'[:16]
            ps_new_owner.save()
            
            admin1 = User.objects.create_user(
                mobile=f'91{sfx1}03', email=f'admin1_{sfx1}@test.com', password='x12345',
                first_name='Admin1', last_name='User', is_staff=True, role='ADMIN'
            )

            product = Product.objects.filter(is_active=True).first()
            ps_dist = create_distributor_id(user=ps_old_owner, product=product, sponsor_distributor=None)

            # Add pre-transfer powerstream bonus for old owner
            pre_transfer_ps_bonus = Decimal('500.00')
            # Get or create ownership period
            ownership_period = DistributorOwnershipPeriod.objects.filter(distributor=ps_dist, owner_user=ps_old_owner).first()
            if not ownership_period:
                ownership_period = DistributorOwnershipPeriod.objects.create(
                    distributor=ps_dist,
                    owner_user=ps_old_owner,
                    from_timestamp=timezone.now()
                )
            
            DistributorRewardOwnershipLedger.objects.create(
                distributor=ps_dist,
                beneficiary_user=ps_old_owner,
                reward_type='POWER_STREAM',
                reward_reference=f'PS_BONUS_{ps_dist.id}',
                amount=pre_transfer_ps_bonus,
                reward_timestamp=timezone.now(),
                ownership_period=ownership_period,
            )
            print(f"[PS-SETUP] Old owner: {ps_old_owner.mobile} ({ps_old_owner.referral_code})")
            print(f"[PS-SETUP] New owner: {ps_new_owner.mobile} ({ps_new_owner.referral_code})")
            print(f"[PS-SETUP] Distributor: {ps_dist.distributor_code}")
            print(f"[PS-SETUP] Pre-transfer PS bonus credited to old owner: {pre_transfer_ps_bonus}")

            # Initiate transfer
            terms = list(DistributorTransferTerms.objects.filter(is_active=True, mandatory=True))
            mandatory_ids = [str(t.id) for t in terms]

            client = APIClient()
            client.force_authenticate(user=ps_old_owner)
            payload = {
                'distributor_id': str(ps_dist.id),
                'reason': 'PS-Scenario transfer',
                'referral_code': ps_new_owner.referral_code,
                'accepted_term_ids': mandatory_ids,
            }
            r = client.post('/api/v1/web/distributor/transfers/', payload, format='json')
            assert r.status_code == 201, f"PS transfer submit failed: {r.status_code} {r.data}"
            ps_req_id = str(r.data['data']['id'])

            # New owner confirm
            client.force_authenticate(user=ps_new_owner)
            r = client.post(f'/api/v1/web/distributor/transfers/{ps_req_id}/new-owner-consent/',
                            {'accepted_term_ids': mandatory_ids}, format='json')
            assert r.status_code == 200, f"PS new owner consent failed: {r.status_code}"

            # Admin approve
            client.force_authenticate(user=admin1)
            r = client.post(f'/api/v1/admin/distributor/transfers/{ps_req_id}/action/',
                            {'action': 'approve', 'admin_notes': 'Approved PS transfer'}, format='json')
            assert r.status_code == 200, f"PS admin approve failed: {r.status_code} {r.data}"

            print(f"[PS-APPROVED] Transfer request {ps_req_id} approved")

            # Verify old owner my IDs (should be empty or not show PS ID)
            client.force_authenticate(user=ps_old_owner)
            r = client.get('/api/v1/web/distributor/ids/')
            assert r.status_code == 200
            old_owner_ids = r.data if isinstance(r.data, list) else r.data.get('data', [])
            ps_in_old_list = any(str(x.get('id')) == str(ps_dist.id) for x in old_owner_ids)
            print(f"[PS-CHECK-OLD] PS ID in old owner's my IDs: {ps_in_old_list} (expected: False)")

            # Verify new owner my IDs (should include PS ID with transfer tag)
            client.force_authenticate(user=ps_new_owner)
            r = client.get('/api/v1/web/distributor/ids/')
            assert r.status_code == 200
            new_owner_ids = r.data if isinstance(r.data, list) else r.data.get('data', [])
            ps_in_new_list = next((x for x in new_owner_ids if str(x.get('id')) == str(ps_dist.id)), None)
            assert ps_in_new_list, "PS ID missing from new owner's my IDs"
            ps_transfer_info = ps_in_new_list.get('transfer_info')
            print(f"[PS-CHECK-NEW] PS ID in new owner's my IDs: True")
            print(f"[PS-TRANSFER-INFO] {ps_transfer_info}")

            assert ps_transfer_info and ps_transfer_info.get('is_transferred_in'), "PS transfer_info not marked as transferred_in"
            # Verify pre-transfer benefit is correctly recorded (Decimal comparison with string conversion)
            assert Decimal(ps_transfer_info.get('pre_transfer_benefit_total_for_old_owner')) == pre_transfer_ps_bonus, \
                f"PS pre-transfer benefit mismatch: {ps_transfer_info.get('pre_transfer_benefit_total_for_old_owner')} != {pre_transfer_ps_bonus}"

            print(f"[PS-VERIFIED] Transfer tag and pre-transfer benefit match!")

            # Check old owner transferred-out tab
            client.force_authenticate(user=ps_old_owner)
            r = client.get('/api/v1/web/distributor/transfers/history/transferred-out-ids/')
            assert r.status_code == 200, f"Transferred-out list failed: {r.status_code} {r.data}"
            transferred_out = r.data.get('data', []) if isinstance(r.data, dict) else r.data
            ps_transferred_out = next((x for x in transferred_out if str(x.get('distributor_id')) == str(ps_dist.id)), None)
            assert ps_transferred_out, "PS ID missing from old owner's transferred-out list"
            print(f"[PS-OLD-OWNER-TRANSFERRED] {ps_transferred_out}")

            print("\n[PASS] TEST SCENARIO 1 PASSED\n")

            # Test scenario 2: Non-PowerStream ID with regular rewards
            print("=" * 100)
            print("TEST SCENARIO 2: Non-PowerStream ID with Pre-Transfer Level Rewards")
            print("=" * 100)

            sfx2 = uuid.uuid4().hex[:8]
            np_old_owner = User.objects.create_user(
                mobile=f'91{sfx2}01', email=f'np_old_{sfx2}@test.com', password='x12345',
                first_name='NP_Old', last_name='Owner'
            )
            np_old_owner.referral_code = f'NPOLD{sfx2.upper()}'[:16]
            np_old_owner.save()
            
            np_new_owner = User.objects.create_user(
                mobile=f'91{sfx2}02', email=f'np_new_{sfx2}@test.com', password='x12345',
                first_name='NP_New', last_name='Owner'
            )
            np_new_owner.referral_code = f'NPNEW{sfx2.upper()}'[:16]
            np_new_owner.save()
            
            admin2 = User.objects.create_user(
                mobile=f'91{sfx2}03', email=f'admin2_{sfx2}@test.com', password='x12345',
                first_name='Admin2', last_name='User', is_staff=True, role='ADMIN'
            )

            np_dist = create_distributor_id(user=np_old_owner, product=product, sponsor_distributor=None)

            # Add pre-transfer level reward
            pre_transfer_reward = Decimal('250.00')
            # Get or create ownership period
            ownership_period_np = DistributorOwnershipPeriod.objects.filter(distributor=np_dist, owner_user=np_old_owner).first()
            if not ownership_period_np:
                ownership_period_np = DistributorOwnershipPeriod.objects.create(
                    distributor=np_dist,
                    owner_user=np_old_owner,
                    from_timestamp=timezone.now()
                )
            
            DistributorRewardOwnershipLedger.objects.create(
                distributor=np_dist,
                beneficiary_user=np_old_owner,
                reward_type='LEVEL_REWARD',
                reward_reference=f'LEVEL_REWARD_{np_dist.id}',
                amount=pre_transfer_reward,
                reward_timestamp=timezone.now(),
                ownership_period=ownership_period_np,
            )
            print(f"[NP-SETUP] Old owner: {np_old_owner.mobile} ({np_old_owner.referral_code})")
            print(f"[NP-SETUP] New owner: {np_new_owner.mobile} ({np_new_owner.referral_code})")
            print(f"[NP-SETUP] Distributor: {np_dist.distributor_code}")
            print(f"[NP-SETUP] Pre-transfer level reward credited to old owner: {pre_transfer_reward}")

            # Initiate transfer
            client.force_authenticate(user=np_old_owner)
            payload = {
                'distributor_id': str(np_dist.id),
                'reason': 'NP-Scenario transfer',
                'referral_code': np_new_owner.referral_code,
                'accepted_term_ids': mandatory_ids,
            }
            r = client.post('/api/v1/web/distributor/transfers/', payload, format='json')
            assert r.status_code == 201
            np_req_id = str(r.data['data']['id'])

            # New owner confirm
            client.force_authenticate(user=np_new_owner)
            r = client.post(f'/api/v1/web/distributor/transfers/{np_req_id}/new-owner-consent/',
                            {'accepted_term_ids': mandatory_ids}, format='json')
            assert r.status_code == 200

            # Admin approve
            client.force_authenticate(user=admin2)
            r = client.post(f'/api/v1/admin/distributor/transfers/{np_req_id}/action/',
                            {'action': 'approve', 'admin_notes': 'Approved NP transfer'}, format='json')
            assert r.status_code == 200

            print(f"[NP-APPROVED] Transfer request {np_req_id} approved")

            # Verify new owner receives ID with transfer tag and pre-transfer benefit
            client.force_authenticate(user=np_new_owner)
            r = client.get('/api/v1/web/distributor/ids/')
            assert r.status_code == 200
            new_owner_ids = r.data if isinstance(r.data, list) else r.data.get('data', [])
            np_in_new_list = next((x for x in new_owner_ids if str(x.get('id')) == str(np_dist.id)), None)
            assert np_in_new_list, "NP ID missing from new owner's my IDs"
            np_transfer_info = np_in_new_list.get('transfer_info')
            print(f"[NP-CHECK-NEW] NP ID in new owner's my IDs: True")
            print(f"[NP-TRANSFER-INFO] {np_transfer_info}")

            assert np_transfer_info and np_transfer_info.get('is_transferred_in'), "NP transfer_info not marked"
            # Verify pre-transfer benefit is correctly recorded (Decimal comparison with string conversion)
            assert Decimal(np_transfer_info.get('pre_transfer_benefit_total_for_old_owner')) == pre_transfer_reward, \
                f"NP pre-transfer benefit mismatch: {np_transfer_info.get('pre_transfer_benefit_total_for_old_owner')} != {pre_transfer_reward}"

            print(f"[NP-VERIFIED] Transfer tag and pre-transfer benefit match!")

            # Check old owner transferred-out list includes NP ID
            client.force_authenticate(user=np_old_owner)
            r = client.get('/api/v1/web/distributor/transfers/history/transferred-out-ids/')
            assert r.status_code == 200
            transferred_out = r.data.get('data', []) if isinstance(r.data, dict) else r.data
            np_transferred_out = next((x for x in transferred_out if str(x.get('distributor_id')) == str(np_dist.id)), None)
            assert np_transferred_out, "NP ID missing from old owner's transferred-out list"
            print(f"[NP-OLD-OWNER-TRANSFERRED] {np_transferred_out}")

            print("\n[PASS] TEST SCENARIO 2 PASSED\n")

            # Final summary
            print("=" * 100)
            print("COMPREHENSIVE TEST SUMMARY")
            print("=" * 100)
            print("\n[PASS] PowerStream Scenario:")
            print(f"   - Old owner had {pre_transfer_ps_bonus} PS bonus pre-transfer")
            print(f"   - Transfer marked: is_transferred_in=True")
            print(f"   - Pre-transfer benefit visible in new owner's ID card: {pre_transfer_ps_bonus}")
            print(f"   - Old owner can see in 'Transferred IDs' tab: Yes")

            print("\n[PASS] Non-PowerStream Scenario:")
            print(f"   - Old owner had {pre_transfer_reward} level reward pre-transfer")
            print(f"   - Transfer marked: is_transferred_in=True")
            print(f"   - Pre-transfer benefit visible in new owner's ID card: {pre_transfer_reward}")
            print(f"   - Old owner can see in 'Transferred IDs' tab: Yes")

            print("\n[PASS] ALL TESTS PASSED - FEATURE 100% FUNCTIONAL")

        finally:
            # Cleanup
            DistributorTransferHistory.objects.all().delete()
            DistributorTransferRequest.objects.all().delete()
