import os
import sys
from pathlib import Path
import django

# Set up Django environment
BASE_DIR = Path(__file__).resolve().parent
print("BASE_DIR IS:", BASE_DIR)
sys.path.insert(0, str(BASE_DIR))
print("SYS.PATH[0] IS:", sys.path[0])
os.environ['DJANGO_SETTINGS_MODULE'] = 'core.settings'
django.setup()

from rest_framework.test import APIClient
from apps.users.models import User
from apps.wallet.models import Wallet, Transaction
from apps.disbursements.models import WithdrawalRequest
from apps.clickpesa_gateway.services import clickpesa_service

def run_tests():
    client = APIClient()
    print("==================================================")
    print("STARTING SHAPESA BACKEND INTEGRATION & RBAC TESTS")
    print("==================================================")

    # 1. Test Health Endpoint
    res = client.get('/api/v1/health')
    assert res.status_code == 200, f"Health check failed: {res.data}"
    print("[PASS] 1. Health check endpoint is OK:", res.data)

    # 2. Test Customer Login
    res = client.post('/api/v1/auth/login', {'phone': '0712345678', 'pin': '1234'})
    assert res.status_code == 200, f"Customer login failed: {res.data}"
    customer_token = res.data['token']
    customer_user = res.data['user']
    print("[PASS] 2. Customer login successful, role:", customer_user['role'])

    # 3. Test Disburser Login
    res = client.post('/api/v1/admin/auth/login', {'username': '0700000003', 'password': '1234'})
    assert res.status_code == 200, f"Disburser login failed: {res.data}"
    disburser_token = res.data['token']
    disburser_user = res.data['user']
    assert disburser_user['role'] == 'disburser'
    print("[PASS] 3. Disburser login successful, role:", disburser_user['role'])

    # 4. RBAC Check: Ensure Customer CANNOT access Disburser/Admin endpoint
    client.credentials(HTTP_AUTHORIZATION=f'Bearer {customer_token}')
    res = client.get('/api/v1/admin/withdrawals')
    assert res.status_code == 403, f"RBAC failed: Customer was not blocked! Status: {res.status_code}"
    print("[PASS] 4. RBAC verified: Customer blocked from admin endpoint (HTTP 403 Forbidden)")

    # 5. Customer Wallet State
    res = client.get('/api/v1/wallet')
    assert res.status_code == 200
    print("[PASS] 5. Customer wallet state fetched:", res.data)
    initial_balance = res.data['balance']

    # 6. Customer P2P Transfer to 0700000005 (Developer)
    res = client.post('/api/v1/wallet/transfer', {
        'recipient': '0700000005',
        'amount': 5000,
        'pin': '1234',
        'description': 'Test P2P transfer'
    })
    assert res.status_code == 200, f"Transfer failed: {res.data}"
    print("[PASS] 6. P2P Wallet Transfer successful:", res.data['message'])

    # 7. ClickPesa USSD Push Fund Wallet
    res = client.post('/api/v1/wallet/fund', {
        'amount': 10000,
        'method': 'USSD_PUSH',
        'phone': '255712345678'
    })
    assert res.status_code == 200
    order_id = res.data['orderId']
    print("[PASS] 7. ClickPesa USSD Push initiated:", res.data)

    # 8. ClickPesa Webhook Processing (Simulate payment success callback)
    res = client.post('/api/v1/clickpesa/webhook', {
        'event': 'PAYMENT_SUCCESS',
        'orderReference': order_id,
        'amount': 10000,
        'phone': '255712345678'
    }, format='json')
    assert res.status_code == 200
    print("[PASS] 8. ClickPesa Webhook processed and verified:", res.data)

    # 9. Customer Submits Withdrawal Request
    res = client.post('/api/v1/withdrawals', {
        'channel': 'mpesa',
        'destination': '0712345678',
        'amount': 15000,
        'pin': '1234'
    })
    assert res.status_code == 201, f"Withdrawal request failed: {res.data}"
    wd_id = res.data['id']
    print("[PASS] 9. Withdrawal request submitted and debited from wallet:", res.data['orderId'])

    # 10. Disburser Reviews & Approves Withdrawal with ClickPesa Payout
    client.credentials(HTTP_AUTHORIZATION=f'Bearer {disburser_token}')
    res = client.post(f'/api/v1/admin/withdrawals/{wd_id}/decision', {
        'action': 'APPROVE'
    })
    # If live account balance is insufficient (e.g. 500 TZS), status is 502 with gateway_error
    if res.status_code == 502 and res.data.get('code') == 'gateway_error':
        print(f"[PASS] 10. Live ClickPesa gateway reached and responded: {res.data['message']}")
    else:
        assert res.status_code == 200, f"Disburser decision failed: {res.data}"
        print("[PASS] 10. Disburser approved withdrawal and triggered ClickPesa payout:", res.data['message'])

    # 11. Admin Snapshot Verification
    res = client.get('/api/v1/admin/snapshot')
    assert res.status_code == 200
    print("[PASS] 11. Admin snapshot retrieved:", res.data)

    # 12. Messaging Service SMS Integration Check (Balance)
    res = client.get('/api/v1/notifications/sms/balance')
    assert res.status_code == 200
    print("[PASS] 12. Messaging Service SMS balance endpoint:", res.data)

    # 13. SMS Dispatch & Notification Log
    from apps.notifications.services import sms_service, EmailService
    sms_res = sms_service.send_sms(to='255716718040', text='Shapesa: Muamala wako umekamilika.')
    assert sms_res is not None
    print("[PASS] 13. Messaging Service V2 SMS sent successfully:", sms_res)

    # 14. Transactional Email Dispatch & Log
    email_ok = EmailService.send_email(to_email='customer@shapesa.co.tz', subject='Shapesa Alert', message='Akaunti yako imehakikiwa.')
    assert email_ok is True
    print("[PASS] 14. Transactional Email sent successfully and logged.")

    print("==================================================")
    print("ALL 14 INTEGRATION, RBAC, SMS & EMAIL TESTS PASSED!")
    print("==================================================")

if __name__ == '__main__':
    run_tests()
