"""
User Deletion Service for RateRight
Handles compliant user account deletion with:
- Soft delete with anonymisation
- Data retention for tax/payment records (7 years)
- Stripe account cleanup
- Email confirmations
"""

from datetime import datetime, timedelta
import logging
import os

from ..extensions import db
from ..models.user import User
from ..models.contract import Contract, Payment
from ..models.job import Job, Application
from ..models.rating import Rating
from ..models.notification import NotificationPreference
from ..models.message import Message
from ..models.file_upload import FileUpload
from .email_service import EmailService
from sqlalchemy import or_

logger = logging.getLogger(__name__)


class UserDeletionService:
    """Service for handling compliant user account deletion"""
    
    @staticmethod
    def soft_delete_user(user_id, deleted_by_admin=False, admin_user_id=None):
        """
        Soft delete a user account with PII anonymisation
        Retains transaction records, ratings, and contracts for compliance (7 years)
        
        Args:
            user_id (int): ID of user to delete
            deleted_by_admin (bool): Whether deletion was initiated by admin
            admin_user_id (int, optional): ID of admin who initiated deletion
            
        Returns:
            tuple: (success: bool, message: str)
        """
        try:
            user = User.query.get(user_id)
            if not user:
                return False, "User not found"
            
            # Store original data for email before anonymisation
            original_email = user.email
            original_name = f"{user.first_name} {user.last_name}"
            
            # Check if already deleted
            if user.is_deleted:
                return False, "User is already deleted"
            
            # Step 1: Preserve PII in legal hold before anonymisation
            logger.info(f"Starting soft delete for user {user_id} ({original_email})")
            
            # Store original PII for legal/compliance purposes
            user.legal_hold_data = {
                'user_id': user.id,
                'first_name': user.first_name,
                'last_name': user.last_name,
                'email': user.email,
                'phone_number': user.phone_number,
                'location': user.location,
                'abn_number': user.abn_number,
                'business_name': user.business_name,
                'primary_trade': user.primary_trade,
                'secondary_trade': user.secondary_trade,
                'white_card_number': user.white_card_number,
                'stripe_account_id': user.stripe_account_id,
                'deleted_by_admin': deleted_by_admin,
                'admin_user_id': admin_user_id,
                'deletion_timestamp': datetime.utcnow().isoformat(),
                'retention_reason': 'Legal compliance and dispute resolution'
            }
            logger.info(f"Legal hold data stored for user {user_id}")
            
            # Step 2: Anonymise PII in User model
            timestamp = datetime.utcnow().timestamp()
            
            user.first_name = f"DeletedUser"
            user.last_name = f"{user.id}"
            user.email = f"deleted_{user.id}_{timestamp}@anonymised.rateright.local"
            user.phone_number = f"0000000000"
            user.location = "Anonymous"
            # ABN must be unique - use timestamp to avoid collisions between deleted users
            user.abn_number = f"{int(timestamp)}{str(user.id).zfill(3)}"[-11:]  # Last 11 digits for ABN format
            user.business_name = f"Deleted Business {user.id}"
            
            # Clear optional PII fields
            user.username = None
            user.primary_trade = None
            user.secondary_trade = None
            user.profile_picture = None
            user.white_card_number = None
            
            # Mark as deleted and inactive
            user.is_deleted = True
            user.is_active = False
            user.account_status = 'deleted'
            user.deleted_at = datetime.utcnow()
            user.anonymised_at = datetime.utcnow()
            
            # Set hard delete date (7 years from now for tax compliance)
            user.scheduled_hard_delete_at = datetime.utcnow() + timedelta(days=365 * 7)
            
            # Clear password hash for security
            user.password_hash = 'DELETED'
            
            # Clear tokens
            user.password_reset_token = None
            user.password_reset_expires = None
            user.email_verification_token = None
            user.email_verification_expires = None
            
            # Step 3: Handle Stripe cleanup
            UserDeletionService._cleanup_stripe_accounts(user)
            
            # Step 4: Soft delete or anonymise related records
            # Keep Payments, Contracts, Ratings for compliance (already linked to anonymised user)
            
            # Delete non-essential data
            UserDeletionService._delete_non_essential_data(user)
            
            # Step 4: Log the deletion (audit logs may be available if model exists)
            try:
                from ..models.audit_log import AuditLog
                audit_entry = AuditLog(
                    user_id=user.id,
                    action='user_account_deleted',
                    details={
                        'deleted_by_admin': deleted_by_admin,
                        'admin_user_id': admin_user_id,
                        'deletion_type': 'soft_delete',
                        'scheduled_hard_delete': user.scheduled_hard_delete_at.isoformat()
                    },
                    ip_address='system'
                )
                db.session.add(audit_entry)
            except ImportError:
                logger.info("AuditLog model not available, skipping audit entry")
            
            # Commit changes
            db.session.commit()
            
            # Step 5: Send confirmation email
            UserDeletionService._send_deletion_confirmation_email(
                original_email, 
                original_name,
                deleted_by_admin
            )
            
            logger.info(f"Successfully soft deleted user {user_id}. Scheduled for hard delete on {user.scheduled_hard_delete_at}")
            
            return True, f"User account successfully deleted and anonymised. All PII has been removed. Transaction records retained for 7 years for tax compliance."
            
        except Exception as e:
            db.session.rollback()
            logger.error(f"Error soft deleting user {user_id}: {str(e)}", exc_info=True)
            return False, f"An error occurred during account deletion: {str(e)}"
    
    @staticmethod
    def _cleanup_stripe_accounts(user):
        """
        Clean up Stripe accounts for deleted user
        
        Args:
            user: User model instance
        """
        if not user.stripe_account_id:
            return
        
        try:
            import stripe
            stripe.api_key = os.environ.get('STRIPE_SECRET_KEY')
            
            if not stripe.api_key:
                logger.warning(f"Stripe API key not configured. Cannot delete Stripe account {user.stripe_account_id}")
                return
            
            # Delete Stripe Connect account
            logger.info(f"Deleting Stripe account {user.stripe_account_id} for user {user.id}")
            
            try:
                stripe.Account.delete(user.stripe_account_id)
                logger.info(f"Successfully deleted Stripe account {user.stripe_account_id}")
            except stripe.error.InvalidRequestError as e:
                # Account may not exist or already deleted
                logger.warning(f"Could not delete Stripe account {user.stripe_account_id}: {str(e)}")
            
            # Clear Stripe reference
            user.stripe_account_id = None
            user.stripe_onboarding_complete = False
            user.stripe_payouts_enabled = False
            user.stripe_charges_enabled = False
            
        except ImportError:
            logger.warning("Stripe library not installed. Cannot delete Stripe accounts.")
        except Exception as e:
            logger.error(f"Error cleaning up Stripe account for user {user.id}: {str(e)}")
    
    @staticmethod
    def _delete_non_essential_data(user):
        """
        Delete non-essential user data that doesn't need to be retained
        
        Essential data (retained): Payments, Contracts, Ratings
        Non-essential data (deleted): Messages, Jobs, Applications, etc.
        
        Args:
            user: User model instance
        """
        try:
            # Delete notification preferences
            NotificationPreference.query.filter_by(user_id=user.id).delete(synchronize_session=False)
            
            # Soft delete file uploads (keep metadata for audit trail)
            file_uploads = FileUpload.query.filter_by(user_id=user.id, is_deleted=False).all()
            for file_upload in file_uploads:
                file_upload.soft_delete()
            
            # KEEP MESSAGES - They contain sender_name snapshots for audit/legal purposes
            # Messages are preserved with anonymized user data for historical record keeping
            # The sender_name field ensures we can still identify who sent messages
            
            # Delete jobs posted by contractor (after 2 years, should be handled by scheduled cleanup)
            # For now, anonymise job poster reference
            if user.role == 'contractor':
                jobs = Job.query.filter_by(contractor_id=user.id).all()
                for job in jobs:
                    # Check if job is older than 2 years
                    if job.created_at and (datetime.utcnow() - job.created_at).days > 730:
                        # Delete applications for old jobs
                        Application.query.filter_by(job_id=job.id).delete(synchronize_session=False)
                        db.session.delete(job)
                    # Otherwise keep job with anonymised contractor reference
            
            # Delete applications by worker (after 2 years)
            if user.role == 'worker':
                applications = Application.query.filter_by(worker_id=user.id).all()
                for app in applications:
                    if app.created_at and (datetime.utcnow() - app.created_at).days > 730:
                        db.session.delete(app)
            
            # Note: We do NOT delete:
            # - Payments (tax records - 7 year retention)
            # - Contracts (legal records - 7 year retention)
            # - Ratings (platform integrity)
            # - Disputes (legal records)
            
            logger.info(f"Deleted non-essential data for user {user.id}")
            
        except Exception as e:
            logger.error(f"Error deleting non-essential data for user {user.id}: {str(e)}")
            raise
    
    @staticmethod
    def _send_deletion_confirmation_email(email, name, deleted_by_admin=False):
        """
        Send account deletion confirmation email
        
        Args:
            email (str): User's email address
            name (str): User's name
            deleted_by_admin (bool): Whether deletion was by admin
        """
        try:
            from flask import current_app
            
            subject = "RateRight Account Deletion Confirmation"
            
            cloudinary_cloud_name = current_app.config.get('CLOUDINARY_CLOUD_NAME', 'dcys6tfcf')
            logo_url = f'https://res.cloudinary.com/{cloudinary_cloud_name}/image/upload/f_png,w_400,q_auto/logo_black_i8fn48.png'
            
            html_content = f"""
            <!DOCTYPE html>
            <html>
            <head>
                <meta charset="UTF-8">
                <meta name="viewport" content="width=device-width, initial-scale=1.0">
            </head>
            <body style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; line-height: 1.6; color: #1e293b; background: #f8fafc; margin: 0; padding: 20px;">
                <div style="max-width: 600px; margin: 0 auto; background: #ffffff; border-radius: 8px; overflow: hidden; box-shadow: 0 2px 8px rgba(0,0,0,0.1);">
                    <div style="background: #ffffff; padding: 30px 40px 20px 40px; text-align: center; border-bottom: 1px solid #e2e8f0;">
                        <img src="{logo_url}" alt="RateRight" style="max-width: 200px; height: auto;">
                    </div>
                    
                    <div style="padding: 40px;">
                        <h2 style="color: #1e293b; margin-top: 0; font-size: 24px; font-weight: 600;">Account Deletion Confirmation</h2>
                        
                        <p>Hi {name},</p>
                        
                        <p>This email confirms that your RateRight account has been {"deleted by an administrator" if deleted_by_admin else "successfully deleted"} as requested.</p>
                        
                        <h3 style="color: #1e293b; font-size: 18px; margin-top: 25px; margin-bottom: 15px;">What has been deleted:</h3>
                        <ul style="padding-left: 20px; margin: 15px 0;">
                            <li style="margin-bottom: 8px;">Your personal information (name, email, phone, address, ABN)</li>
                            <li style="margin-bottom: 8px;">Your profile and preferences</li>
                            <li style="margin-bottom: 8px;">Messages and communications</li>
                            <li style="margin-bottom: 8px;">Job postings older than 2 years</li>
                            <li style="margin-bottom: 8px;">Applications older than 2 years</li>
                            <li style="margin-bottom: 8px;">Your Stripe payment account</li>
                        </ul>
                        
                        <div style="background: #fef3c7; border-left: 4px solid #f59e0b; padding: 12px; margin: 20px 0; font-size: 14px;">
                            <strong>⚖️ Data Retention for Compliance</strong><br>
                            In accordance with our Privacy Policy and Australian tax law, the following data has been <strong>anonymised but retained</strong>:
                            <ul style="margin-top: 10px; margin-bottom: 0; padding-left: 20px;">
                                <li style="margin-bottom: 6px;"><strong>Transaction records:</strong> Retained for 7 years (ATO requirement)</li>
                                <li style="margin-bottom: 6px;"><strong>Payment records:</strong> Retained for 7 years (tax compliance)</li>
                                <li style="margin-bottom: 6px;"><strong>Contracts:</strong> Retained for 7 years (legal requirement)</li>
                                <li style="margin-bottom: 6px;"><strong>Ratings:</strong> Retained for platform integrity (anonymised)</li>
                            </ul>
                        </div>
                        
                        <p>After 7 years, all remaining data will be permanently deleted from our systems.</p>
                        
                        <p>If you believe this deletion was made in error or have any questions, please contact us at <a href="mailto:admin@rateright.com.au" style="color: #9acd32; text-decoration: none;">admin@rateright.com.au</a> within 7 days.</p>
                        
                        <p>Thank you for using RateRight.</p>
                        
                        <div style="margin-top: 30px; padding: 15px 20px; background: #1e293b; color: #ffffff; border-radius: 6px; font-size: 12px; line-height: 1.6;">
                            <table style="width: 100%; border-collapse: collapse;">
                                <tr>
                                    <td style="width: 50%; vertical-align: top; padding-right: 15px;">
                                        <strong style="font-size: 14px;">RateRight Pty Ltd</strong><br>
                                        ABN: 46 689 397 582<br>
                                        <a href="https://rateright.com.au" style="color: #9acd32; text-decoration: none;">rateright.com.au</a>
                                    </td>
                                    <td style="width: 50%; vertical-align: top; padding-left: 15px; border-left: 1px solid #475569; font-size: 11px; color: #cbd5e1;">
                                        RateRight acts as a platform facilitator only. Independent contractor relationships remain between hirers and workers.
                                    </td>
                                </tr>
                            </table>
                        </div>
                        <p style="text-align: center; font-size: 11px; color: #64748b; margin-top: 15px;">This is an automated message. Please do not reply.</p>
                    </div>
                </div>
            </body>
            </html>
            """
            
            EmailService.send_email(email, subject, "", html_content)
            logger.info(f"Sent deletion confirmation email to {email}")
            
        except Exception as e:
            logger.error(f"Error sending deletion confirmation email to {email}: {str(e)}")
    
    @staticmethod
    def hard_delete_user(user_id):
        """
        Permanently delete a user and all related records
        Should only be called for users past their scheduled_hard_delete_at date (7 years)
        
        Args:
            user_id (int): ID of user to permanently delete
            
        Returns:
            tuple: (success: bool, message: str)
        """
        try:
            user = User.query.get(user_id)
            if not user:
                return False, "User not found"
            
            # Safety check: only delete if scheduled date has passed
            if user.scheduled_hard_delete_at and datetime.utcnow() < user.scheduled_hard_delete_at:
                days_remaining = (user.scheduled_hard_delete_at - datetime.utcnow()).days
                return False, f"Cannot hard delete user. Scheduled deletion date not reached ({days_remaining} days remaining)"
            
            logger.info(f"Starting hard delete for user {user_id}")
            
            # Delete all related records (now past retention period)
            # Delete payments
            for contract in Contract.query.filter(
                or_(Contract.worker_id == user.id, Contract.contractor_id == user.id)
            ).all():
                Payment.query.filter_by(contract_id=contract.id).delete()
            
            # Delete contracts
            Contract.query.filter(
                or_(Contract.worker_id == user.id, Contract.contractor_id == user.id)
            ).delete(synchronize_session=False)
            
            # Delete ratings
            Rating.query.filter(
                or_(Rating.rater_id == user.id, Rating.rated_id == user.id)
            ).delete(synchronize_session=False)
            
            # Delete disputes (if model exists)
            try:
                from ..models.dispute import Dispute
                Dispute.query.filter_by(raised_by=user.id).delete(synchronize_session=False)
            except ImportError:
                pass
            
            # Delete audit logs (if model exists)
            try:
                from ..models.audit_log import AuditLog
                AuditLog.query.filter_by(user_id=user.id).delete(synchronize_session=False)
            except ImportError:
                pass
            
            # Delete remaining jobs and applications
            if user.role == 'contractor':
                jobs = Job.query.filter_by(contractor_id=user.id).all()
                for job in jobs:
                    Application.query.filter_by(job_id=job.id).delete()
                    db.session.delete(job)
            
            if user.role == 'worker':
                Application.query.filter_by(worker_id=user.id).delete()
            
            # Delete file uploads
            FileUpload.query.filter_by(user_id=user.id).delete(synchronize_session=False)
            
            # Finally, delete the user
            db.session.delete(user)
            db.session.commit()
            
            logger.info(f"Successfully hard deleted user {user_id} and all related records")
            
            return True, "User permanently deleted from system"
            
        except Exception as e:
            db.session.rollback()
            logger.error(f"Error hard deleting user {user_id}: {str(e)}", exc_info=True)
            return False, f"An error occurred during permanent deletion: {str(e)}"
