
from flask import request, jsonify
from flask_jwt_extended import jwt_required, get_jwt_identity
from datetime import datetime, date, timedelta
import logging
import uuid

from . import legal_bp
from ...models import Contract, Payment, Invoice, Job, User
from ...extensions import db, limiter, csrf
from ...utils.compliance import (
    calculate_gst, generate_payment_reference, 
    calculate_withholding_tax, validate_contract_terms, calculate_total_with_gst
)

# Security: Maximum payment amount to prevent abuse
MAX_PAYMENT_AMOUNT_AUD = 1000000  # $1M AUD

logger = logging.getLogger(__name__)


@legal_bp.route('/contracts', methods=['POST'])
@jwt_required()
def create_contract():
    """Create new contract between contractor and worker"""
    try:
        current_user_id = get_jwt_identity()
        data = request.get_json()
        
        # Validation
        required_fields = ['job_id', 'worker_id', 'agreed_rate', 'start_date', 'end_date', 'scope_of_work']
        for field in required_fields:
            if not data.get(field):
                return jsonify({"error": f"{field} is required"}), 400
        
        # Verify job ownership
        job = Job.query.get(data['job_id'])
        if not job or job.contractor_id != current_user_id:
            return jsonify({"error": "Job not found or unauthorized"}), 404
        
        # Verify worker exists
        worker = User.query.get(data['worker_id'])
        if not worker or worker.role != 'worker':
            return jsonify({"error": "Invalid worker"}), 400
        
        # Parse dates
        start_date = datetime.strptime(data['start_date'], '%Y-%m-%d').date()
        end_date = datetime.strptime(data['end_date'], '%Y-%m-%d').date()
        
        # Validate contract terms
        is_valid, validation_errors = validate_contract_terms(
            start_date, end_date, float(data['agreed_rate'])
        )
        if not is_valid:
            return jsonify({"error": "Contract validation failed", "details": validation_errors}), 400
        
        # Create contract
        contract = Contract(
            job_id=data['job_id'],
            contractor_id=current_user_id,
            worker_id=data['worker_id'],
            agreed_rate=data['agreed_rate'],
            rate_type=data.get('rate_type', 'total'),
            start_date=start_date,
            end_date=end_date,
            scope_of_work=data['scope_of_work'],
            payment_terms=data.get('payment_terms', 'completion'),
            payment_schedule=data.get('payment_schedule')
        )
        
        db.session.add(contract)
        db.session.commit()
        
        return jsonify({
            "message": "Contract created successfully",
            "contract": {
                "id": contract.id,
                "job_id": contract.job_id,
                "agreed_rate": float(contract.agreed_rate),
                "start_date": contract.start_date.isoformat(),
                "end_date": contract.end_date.isoformat(),
                "status": contract.status,
                "total_value": contract.calculate_total_value()
            }
        }), 201
        
    except ValueError as e:
        return jsonify({"error": f"Invalid date format: {str(e)}"}), 400
    except Exception as e:
        db.session.rollback()
        return jsonify({"error": f"Contract creation failed: {str(e)}"}), 500


@legal_bp.route('/contracts/<int:contract_id>/sign', methods=['PUT'])
@jwt_required()
def sign_contract(contract_id):
    """Sign contract (contractor or worker)"""
    try:
        current_user_id = get_jwt_identity()
        contract = Contract.query.get_or_404(contract_id)
        
        # Check authorization
        if current_user_id not in [contract.contractor_id, contract.worker_id]:
            return jsonify({"error": "Unauthorized to sign this contract"}), 403
        
        # Sign contract
        if contract.contractor_id == current_user_id:
            contract.contractor_signed = True
            contract.contractor_signed_date = datetime.utcnow()
        elif contract.worker_id == current_user_id:
            contract.worker_signed = True
            contract.worker_signed_date = datetime.utcnow()
        
        # Update status if both signed
        if contract.is_fully_signed():
            contract.status = 'signed'
        
        db.session.commit()
        
        return jsonify({
            "message": "Contract signed successfully",
            "contract_status": contract.status,
            "fully_signed": contract.is_fully_signed()
        })
        
    except Exception as e:
        db.session.rollback()
        return jsonify({"error": f"Contract signing failed: {str(e)}"}), 500


@legal_bp.route('/payments', methods=['POST'])
@limiter.limit("10 per hour")  # Rate limit: 10 payment attempts per hour
def process_stripe_payment():
    """Process secure Stripe Elements payment for contract escrow"""
    from flask_login import login_required, current_user
    from functools import wraps
    
    # Use Flask-Login authentication instead of JWT
    if not current_user.is_authenticated:
        logger.warning(f"Unauthenticated payment attempt from IP: {request.remote_addr}")
        return jsonify({"error": "Authentication required"}), 401
    
    # Generate idempotency key for this payment attempt
    idempotency_key = str(uuid.uuid4())
    
    try:
        from ...services.stripe_service import stripe_service
        import stripe
        
        current_user_id = current_user.id
        logger.info(f"Payment processing initiated by user {current_user_id}")
        
        data = request.get_json()
        
        # Validate required fields
        required_fields = ['contract_id', 'payment_method_id']
        for field in required_fields:
            if not data.get(field):
                logger.warning(f"Missing required field '{field}' in payment request")
                return jsonify({"error": f"{field} is required"}), 400
        
        contract_id = data['contract_id']
        
        # Start atomic transaction
        try:
            # Verify contract access with row lock
            contract = Contract.query.filter_by(id=contract_id).with_for_update().first()
            if not contract or contract.contractor_id != current_user_id:
                logger.warning(f"Unauthorized payment attempt for contract {contract_id} by user {current_user_id}")
                return jsonify({"error": "Contract not found or unauthorized"}), 404
            
            # Validate contract state before accepting payment
            if contract.status in ['cancelled', 'completed', 'disputed']:
                logger.warning(f"Payment attempt for contract {contract_id} with invalid status: {contract.status}")
                return jsonify({
                    "error": f"Cannot process payment - contract status is '{contract.status}'"
                }), 400
            
            # Validate payment amount matches contract terms
            expected_amount = float(contract.agreed_rate)
            
            # Try to parse duration as numeric hours first (new format)
            try:
                hours = int(contract.job.duration)
            except (ValueError, TypeError):
                # Legacy format - use mapping
                duration_hours = {
                    'half_day': 4, 'full_day': 8, 'long_day': 10,
                    '2_days': 16, '3_5_days': 32, '1_week_plus': 40,
                    # Legacy format support
                    '4 hours': 4, '8 hours': 8, '10 hours': 10,
                    '2 days': 16, '3-5 days': 32, '1 week+': 40
                }
                hours = duration_hours.get(contract.job.duration, 8)
            
            expected_total = expected_amount * hours
            
            # Check if payment already exists (with row locking to prevent race condition)
            existing_payment = Payment.query.filter(
                Payment.contract_id == contract.id,
                Payment.status.in_(['pending_payment', 'held_escrow', 'pending_release'])
            ).with_for_update().first()
            
            if existing_payment:
                logger.warning(f"Duplicate payment attempt for contract {contract_id}")
                return jsonify({"error": "Payment already exists for this contract"}), 400
            
            # Create payment record FIRST (before Stripe call)
            payment = Payment(
                contract_id=contract.id,
                payment_reference=generate_payment_reference(),
                dispute_period_days=7,  # 7-day dispute window
                status='pending_payment'
            )
            
            # Set contract relationship so calculate_amounts can access it
            payment.contract = contract
            
            # Calculate payment amounts
            payment.calculate_amounts()
            
            # Validate calculated amount matches expected
            amount_diff = abs(float(payment.gross_amount) - expected_total)
            if amount_diff > 1.0:  # Allow $1 difference for rounding
                logger.error(f"Payment amount mismatch for contract {contract_id}: expected ${expected_total}, got ${payment.gross_amount}")
            
            # Validate payment amount is within acceptable limits
            if payment.gross_amount > MAX_PAYMENT_AMOUNT_AUD:
                logger.error(f"Payment amount ${payment.gross_amount} exceeds maximum for contract {contract_id}")
                return jsonify({
                    "error": f"Payment amount ${payment.gross_amount} exceeds maximum allowed ${MAX_PAYMENT_AMOUNT_AUD}"
                }), 400
            
            logger.info(f"Payment amounts calculated for contract {contract_id} - Gross: ${payment.gross_amount}")
            
            # Add payment to session (but don't commit yet)
            db.session.add(payment)
            db.session.flush()  # Get payment ID without committing
            
            # Create Stripe PaymentIntent with idempotency key
            try:
                stripe_intent = stripe_service.create_payment_intent(
                    amount_aud=float(payment.gross_amount),
                    metadata={
                        'payment_id': payment.id,
                        'contract_id': contract.id,
                        'payment_reference': payment.payment_reference
                    },
                    idempotency_key=idempotency_key
                )
                logger.info(f"Stripe PaymentIntent created: {stripe_intent.id} for payment {payment.id}")
            except Exception as intent_error:
                logger.error(f"Failed to create PaymentIntent for payment {payment.id}: {intent_error}")
                db.session.rollback()
                return jsonify({
                    "error": "Failed to create payment intent", 
                    "details": str(intent_error)
                }), 400
            
            # Update payment with Stripe details
            payment.stripe_payment_intent_id = stripe_intent.id
            payment.date_initiated = datetime.utcnow()
            
            # Confirm payment with the payment method from Stripe Elements
            try:
                logger.info(f"Confirming payment {payment.id} with method: {data['payment_method_id']}")
                
                # Build dynamic return URL for 3D Secure
                from flask import url_for
                return_url = url_for('payment_return_handler', 
                                    contract_id=contract.id,
                                    _external=True, 
                                    _scheme='https')
                
                # Use a different idempotency key for confirm operation (different endpoint)
                confirm_idempotency_key = f"{idempotency_key}-confirm"
                
                confirmed_intent = stripe.PaymentIntent.confirm(
                    stripe_intent.id,
                    payment_method=data['payment_method_id'],
                    return_url=return_url,
                    idempotency_key=confirm_idempotency_key
                )
                logger.info(f"Payment {payment.id} confirmed, status: {confirmed_intent.status}")
            except Exception as stripe_error:
                logger.error(f"Payment confirmation failed for payment {payment.id}: {stripe_error}")
                payment.status = 'payment_failed'
                db.session.commit()
                return jsonify({
                    "error": "Payment confirmation failed", 
                    "details": str(stripe_error)
                }), 400
            
            # Update payment status based on Stripe response
            payment.stripe_status = confirmed_intent.status
            
            if confirmed_intent.status == 'requires_capture':
                # Manual capture (escrow) - payment authorized but not yet captured - THIS IS CORRECT
                payment.status = 'held_escrow'
                payment.date_held_escrow = datetime.utcnow()
                payment.dispute_deadline = datetime.utcnow() + timedelta(days=payment.dispute_period_days)
                
                # Update payment status - contract becomes 'active' only after both payment AND signatures
                contract.payment_status = 'paid'
                if contract.is_fully_signed():
                    contract.status = 'active'
                    logger.info(f"Contract {contract_id} activated after payment and signatures")
                    # Send notification to worker
                    try:
                        from app.services.notification_service import notification_service
                        from app.models.notification import NotificationType
                        notification_service.send_notification(
                            user_id=contract.worker_id,
                            notification_type=NotificationType.CONTRACT_AWARDED,
                            title="Contract is Now Active! 🎉",
                            content=f"The contract for '{contract.job.title}' is now active. Payment has been secured in escrow. You can start work!",
                            priority=1,
                            category="contract",
                            action_url=url_for('contract_review', contract_id=contract.id, _external=True)
                        )
                    except Exception as e:
                        logger.error(f"Failed to send contract activation notification: {e}")
                
                logger.info(f"Payment {payment.id} authorized and held in escrow")
                
            elif confirmed_intent.status == 'succeeded':
                # Payment already captured (shouldn't happen with capture_method=manual, but handle it)
                logger.warning(f"Payment {payment.id} auto-captured despite manual capture setting")
                payment.status = 'held_escrow'
                payment.date_held_escrow = datetime.utcnow()
                payment.dispute_deadline = datetime.utcnow() + timedelta(days=payment.dispute_period_days)
                contract.payment_status = 'paid'
                if contract.is_fully_signed():
                    contract.status = 'active'
                    
            elif confirmed_intent.status == 'requires_action':
                payment.status = 'requires_action'
                logger.info(f"Payment {payment.id} requires additional action (3D Secure)")
                # Commit the payment record for 3D Secure flow
                db.session.commit()
                return jsonify({
                    "requires_action": True,
                    "payment_intent_client_secret": confirmed_intent.client_secret,
                    "payment_intent_id": confirmed_intent.id
                }), 200
                
            else:
                payment.status = 'payment_failed'
                logger.error(f"Payment {payment.id} failed with unexpected status: {confirmed_intent.status}")
                db.session.commit()
                return jsonify({
                    "error": "Payment authorization failed",
                    "status": confirmed_intent.status
                }), 400
            
            # Commit all changes atomically
            db.session.commit()
            logger.info(f"Payment {payment.id} successfully processed for contract {contract_id}")
            
            return jsonify({
                "message": "Payment processed successfully - funds held in secure escrow",
                "payment": {
                    "id": payment.id,
                    "payment_reference": payment.payment_reference,
                    "gross_amount": float(payment.gross_amount),
                    "platform_fee": float(payment.platform_fee),
                    "gst_amount": float(payment.gst_amount),
                    "net_to_worker": float(payment.net_to_worker),
                    "status": payment.status,
                    "dispute_deadline": payment.dispute_deadline.isoformat() if payment.dispute_deadline else None
                },
                "contract": {
                    "id": contract.id,
                    "status": contract.status
                }
            }), 201
            
        except Exception as db_error:
            db.session.rollback()
            logger.error(f"Database error during payment processing: {db_error}")
            raise
        
    except Exception as e:
        db.session.rollback()
        logger.error(f"Payment processing failed: {str(e)}", exc_info=True)
        return jsonify({"error": f"Payment processing failed: {str(e)}"}), 500


@legal_bp.route('/contract/<int:contract_id>/mark-complete', methods=['POST'])
@jwt_required()
def mark_contract_complete(contract_id):
    """Worker marks contract work as complete"""
    try:
        current_user_id = get_jwt_identity()
        
        contract = Contract.query.get_or_404(contract_id)
        
        # Only worker can mark as complete
        if contract.worker_id != current_user_id:
            return jsonify({"error": "Only the worker can mark work as complete"}), 403
        
        if contract.status != 'active':
            return jsonify({"error": "Contract must be active to mark complete"}), 400
        
        # Update contract status
        contract.status = 'pending_review'
        
        # Find associated payment
        payment = contract.payments.filter_by(status='held_escrow').first()
        if payment:
            payment.status = 'pending_release'
            payment.release_conditions_met = True
        
        db.session.commit()
        
        return jsonify({
            "message": "Work marked as complete - awaiting contractor review",
            "contract_status": contract.status,
            "payment_status": payment.status if payment else None
        }), 200
        
    except Exception as e:
        db.session.rollback()
        return jsonify({"error": f"Failed to mark complete: {str(e)}"}), 500


@legal_bp.route('/contract/<int:contract_id>/approve-completion', methods=['POST'])
@jwt_required()
def approve_contract_completion(contract_id):
    """Contractor approves work completion and releases payment"""
    try:
        from ...services.stripe_service import stripe_service
        from flask import current_app
        
        current_user_id = get_jwt_identity()
        
        contract = Contract.query.get_or_404(contract_id)
        
        # Only contractor can approve completion
        if contract.contractor_id != current_user_id:
            return jsonify({"error": "Only the contractor can approve completion"}), 403
        
        if contract.status != 'pending_review':
            return jsonify({"error": "Contract is not pending completion review"}), 400
        
        # Find payment in escrow
        payment = contract.payments.filter_by(status='pending_release').first()
        if not payment:
            return jsonify({"error": "No payment found in escrow"}), 404
        
        # Get worker for payout
        worker = contract.worker
        
        print(f"💰 Processing payment release for contract {contract_id}")
        print(f"   Worker: {worker.email} (ID: {worker.id})")
        print(f"   Amount: ${payment.net_to_worker}")
        
        # Step 1: Capture payment from escrow
        if payment.stripe_payment_intent_id:
            print(f"📥 Capturing payment from escrow...")
            captured_payment = stripe_service.capture_payment(
                payment.stripe_payment_intent_id
            )
            payment.stripe_status = captured_payment.status
            print(f"✅ Payment captured: {captured_payment.status}")
        
        # Step 2: Transfer to worker's Stripe account
        transfer_result = None
        
        # TEST MODE: Check for test mode in config
        test_mode = current_app.config.get('STRIPE_TEST_MODE', True)
        
        if test_mode:
            # TEST MODE: Simulate successful transfer
            print(f"🧪 TEST MODE: Simulating transfer to worker")
            transfer_result = {
                'id': f'tr_test_{payment.id}',
                'status': 'succeeded',
                'test_mode': True
            }
            payment.stripe_transfer_id = transfer_result['id']
            payment.stripe_transfer_status = 'test_succeeded'
            print(f"✅ TEST: Simulated transfer {transfer_result['id']}")
        else:
            # PRODUCTION: Check if worker has Stripe account
            if not worker.stripe_account_id:
                db.session.rollback()
                return jsonify({
                    "error": "Worker has not set up their payout account yet",
                    "action_required": "worker_onboarding"
                }), 400
            
            # Transfer to worker
            print(f"💸 Transferring ${payment.net_to_worker} to worker's Stripe account...")
            try:
                transfer = stripe_service.transfer_to_worker(
                    amount_aud=float(payment.net_to_worker),
                    destination_account_id=worker.stripe_account_id,
                    metadata={
                        'contract_id': contract.id,
                        'payment_reference': payment.payment_reference,
                        'worker_email': worker.email,
                        'job_title': contract.job.title
                    }
                )
                
                payment.stripe_transfer_id = transfer.id
                payment.stripe_transfer_status = 'succeeded'  # Transfers are immediate
                transfer_result = transfer
                print(f"✅ Transfer created: {transfer.id}")
                
            except Exception as transfer_error:
                print(f"❌ Transfer failed: {transfer_error}")
                db.session.rollback()
                return jsonify({
                    "error": "Failed to transfer payment to worker",
                    "details": str(transfer_error)
                }), 500
        
        # Step 3: Update payment and contract status
        payment.status = 'transferred'
        payment.date_released = datetime.utcnow()
        contract.mark_as_completed()  # Use method to properly set status, completion_status, and increment jobs_completed
        
        # Auto-generate invoice for GST-registered workers
        try:
            invoice = payment.auto_generate_invoice()
            if invoice:
                print(f"📄 Auto-generated invoice: {invoice.invoice_number}")
        except Exception as invoice_error:
            print(f"⚠️ Invoice generation failed: {invoice_error}")
        
        db.session.commit()
        
        print(f"🎉 Payment distribution complete!")
        
        response_data = {
            "message": "Work approved and payment distributed successfully",
            "contract_status": contract.status,
            "payment_status": payment.status,
            "amount_released": float(payment.net_to_worker),
            "transfer_id": payment.stripe_transfer_id
        }
        
        if test_mode:
            response_data["test_mode"] = True
            response_data["note"] = "Running in test mode - no actual transfer to Stripe"
        
        return jsonify(response_data), 200
        
    except Exception as e:
        print(f"❌ Error in payment distribution: {e}")
        db.session.rollback()
        return jsonify({"error": f"Failed to approve completion: {str(e)}"}), 500


@legal_bp.route('/contract/<int:contract_id>/dispute-completion', methods=['POST'])
@jwt_required()
def dispute_contract_completion(contract_id):
    """Contractor disputes work completion"""
    try:
        current_user_id = get_jwt_identity()
        data = request.get_json()
        
        contract = Contract.query.get_or_404(contract_id)
        
        # Only contractor can dispute
        if contract.contractor_id != current_user_id:
            return jsonify({"error": "Only the contractor can dispute completion"}), 403
        
        if contract.status != 'pending_review':
            return jsonify({"error": "Contract is not pending completion review"}), 400
        
        dispute_reason = data.get('reason', 'Work does not meet requirements')
        
        # Update contract status
        contract.status = 'disputed'
        
        # Find payment and mark as disputed
        payment = contract.payments.filter_by(status='pending_release').first()
        if payment:
            payment.status = 'disputed'
        
        db.session.commit()
        
        return jsonify({
            "message": "Completion disputed - contract requires resolution",
            "contract_status": contract.status,
            "dispute_reason": dispute_reason,
            "next_steps": "Contact support or resolve directly with worker"
        }), 200
        
    except Exception as e:
        db.session.rollback()
        return jsonify({"error": f"Failed to dispute completion: {str(e)}"}), 500


@legal_bp.route('/contract/<int:contract_id>/cancel', methods=['POST'])
@jwt_required()
def cancel_contract(contract_id):
    """Cancel contract and refund payment if applicable"""
    try:
        from ..services.stripe_service import stripe_service
        
        current_user_id = get_jwt_identity()
        data = request.get_json()
        
        contract = Contract.query.get_or_404(contract_id)
        
        # Both parties can cancel under certain conditions
        if contract.contractor_id != current_user_id and contract.worker_id != current_user_id:
            return jsonify({"error": "Unauthorized to cancel this contract"}), 403
        
        if contract.status in ['completed', 'cancelled']:
            return jsonify({"error": "Contract cannot be cancelled"}), 400
        
        cancellation_reason = data.get('reason', 'Contract cancelled by agreement')
        
        # Handle payment refund if exists
        payment = contract.payments.filter_by(status='held_escrow').first()
        if payment and payment.stripe_payment_intent_id:
            # Refund the payment
            refund = stripe_service.refund_payment(
                payment.stripe_payment_intent_id,
                reason='requested_by_customer'
            )
            payment.status = 'refunded'
            payment.stripe_status = 'refunded'
        
        # Update contract status
        contract.status = 'cancelled'
        
        db.session.commit()
        
        return jsonify({
            "message": "Contract cancelled successfully",
            "contract_status": contract.status,
            "payment_refunded": payment.status == 'refunded' if payment else False,
            "cancellation_reason": cancellation_reason
        }), 200
        
    except Exception as e:
        db.session.rollback()
        return jsonify({"error": f"Failed to cancel contract: {str(e)}"}), 500


@legal_bp.route('/payments/<int:payment_id>/status', methods=['GET'])
@jwt_required()
def get_payment_status(payment_id):
    """Get current payment status and details"""
    try:
        current_user_id = get_jwt_identity()
        
        payment = Payment.query.get_or_404(payment_id)
        contract = payment.contract
        
        # Check authorization
        if contract.contractor_id != current_user_id and contract.worker_id != current_user_id:
            return jsonify({"error": "Unauthorized to view this payment"}), 403
        
        return jsonify({
            "payment": {
                "id": payment.id,
                "reference": payment.payment_reference,
                "status": payment.status,
                "gross_amount": float(payment.gross_amount),
                "platform_fee": float(payment.platform_fee),
                "net_to_worker": float(payment.net_to_worker),
                "date_initiated": payment.date_initiated.isoformat(),
                "date_held_escrow": payment.date_held_escrow.isoformat() if payment.date_held_escrow else None,
                "date_released": payment.date_released.isoformat() if payment.date_released else None,
                "dispute_deadline": payment.dispute_deadline.isoformat() if payment.dispute_deadline else None,
                "stripe_status": payment.stripe_status
            },
            "contract_status": contract.status
        }), 200
        
    except Exception as e:
        return jsonify({"error": f"Failed to get payment status: {str(e)}"}), 500


@legal_bp.route('/stripe/webhook', methods=['POST'])
@limiter.limit("100 per minute")  # Rate limit webhooks to prevent DoS
@csrf.exempt  # Webhooks don't use CSRF tokens - use Stripe signature instead
def stripe_webhook():
    """Handle Stripe webhooks"""
    from .stripe_webhooks import handle_stripe_webhook
    return handle_stripe_webhook()


@legal_bp.route('/invoices', methods=['POST'])
@jwt_required()
def generate_invoice():
    """Generate GST-compliant invoice"""
    try:
        current_user_id = get_jwt_identity()
        data = request.get_json()
        
        if not data.get('payment_id'):
            return jsonify({"error": "payment_id is required"}), 400
        
        payment = Payment.query.get(data['payment_id'])
        if not payment:
            return jsonify({"error": "Payment not found"}), 404
        
        contract = payment.contract
        
        # Check if user is the worker (invoice issuer)
        if contract.worker_id != current_user_id:
            return jsonify({"error": "Only the worker can generate invoices"}), 403
        
        # Check if worker is GST registered
        worker = User.query.get(contract.worker_id)
        if not worker.gst_registered:
            return jsonify({"error": "Worker must be GST registered to issue invoices"}), 400
        
        # Use the auto_generate_invoice method for consistency
        invoice = payment.auto_generate_invoice()
        
        if not invoice:
            return jsonify({"error": "Failed to generate invoice. Invoice may already exist or payment data is invalid."}), 400
        
        db.session.commit()
        
        return jsonify({
            "message": "GST invoice generated successfully",
            "invoice": {
                "id": invoice.id,
                "invoice_number": invoice.invoice_number,
                "amount_ex_gst": float(invoice.amount_ex_gst),
                "gst_amount": float(invoice.gst_amount),
                "total_amount": float(invoice.total_amount),
                "due_date": invoice.due_date.isoformat(),
                "supplier_abn": invoice.supplier_abn,
                "buyer_abn": invoice.buyer_abn
            }
        }), 201
        
    except Exception as e:
        db.session.rollback()
        return jsonify({"error": f"Invoice generation failed: {str(e)}"}), 500


@legal_bp.route('/validate-abn', methods=['POST'])
def validate_abn():
    """Validate Australian Business Number"""
    try:
        data = request.get_json()
        abn = data.get('abn')
        
        if not abn:
            return jsonify({"error": "ABN is required"}), 400
        
        from ...utils.validators import validate_abn
        is_valid = validate_abn(abn)
        
        # Check if ABN is registered with a user
        user = User.query.filter_by(abn_number=abn).first()
        gst_registered = user.gst_registered if user else False
        
        # Calculate withholding tax requirement
        withholding_required = not gst_registered
        
        return jsonify({
            "abn": abn,
            "is_valid": is_valid,
            "gst_registered": gst_registered,
            "withholding_tax_required": withholding_required,
            "registered_user": bool(user)
        })
        
    except Exception as e:
        return jsonify({"error": f"ABN validation failed: {str(e)}"}), 500
