
from django.core.management.base import BaseCommand
from django.utils import timezone
from decimal import Decimal
from datetime import date
from dateutil.relativedelta import relativedelta

from hr.models import Employee, Payslip, Bonus
from expenditure.models import Expense, ExpenseCategory
from accounts.models import CustomUser


class Command(BaseCommand):
    help = 'Generate salary and bonus expenses from HR payslips'

    def add_arguments(self, parser):
        parser.add_argument(
            '--month',
            type=int,
            help='Month to generate expenses for (1-12)',
        )
        parser.add_argument(
            '--year',
            type=int,
            help='Year to generate expenses for',
        )
        parser.add_argument(
            '--dry-run',
            action='store_true',
            help='Show what would be created without actually creating expenses',
        )

    def handle(self, *args, **options):
        # Get month and year
        target_month = options.get('month', date.today().month)
        target_year = options.get('year', date.today().year)
        dry_run = options.get('dry_run', False)

        self.stdout.write(
            self.style.SUCCESS(
                f'Generating payroll expenses for {target_month}/{target_year}'
            )
        )

        # Get or create salary and bonus categories
        salary_category, created = ExpenseCategory.objects.get_or_create(
            name='Employee Salaries',
            defaults={'description': 'Monthly employee salary payments'}
        )
        if created:
            self.stdout.write(f'Created salary category: {salary_category.name}')

        bonus_category, created = ExpenseCategory.objects.get_or_create(
            name='Employee Bonuses',
            defaults={'description': 'Employee bonus payments'}
        )
        if created:
            self.stdout.write(f'Created bonus category: {bonus_category.name}')

        # Get payslips for the target month/year
        payslips = Payslip.objects.filter(
            pay_period_start__year=target_year,
            pay_period_start__month=target_month,
            is_generated=True
        )

        if not payslips.exists():
            self.stdout.write(
                self.style.WARNING(
                    f'No payslips found for {target_month}/{target_year}. '
                    'Make sure payslips are generated first.'
                )
            )
            return

        created_expenses = 0
        total_salary_amount = Decimal('0.00')
        total_bonus_amount = Decimal('0.00')

        # Get a system user to create expenses (preferably HR manager or admin)
        system_user = CustomUser.objects.filter(is_superuser=True).first()
        if not system_user:
            system_user = CustomUser.objects.filter(is_staff=True).first()

        for payslip in payslips:
            employee = payslip.employee

            # Check if salary expense already exists
            existing_salary_expense = Expense.objects.filter(
                employee=employee,
                category=salary_category,
                expense_date__year=target_year,
                expense_date__month=target_month,
                title__icontains='salary'
            ).first()

            if not existing_salary_expense:
                salary_expense_data = {
                    'employee': employee,
                    'category': salary_category,
                    'related_payslip': payslip,
                    'title': f'Salary - {employee.full_name} - {payslip.pay_period_start.strftime("%B %Y")}',
                    'description': f'Monthly salary payment for {employee.full_name} (Payslip: {payslip.payslip_number})',
                    'amount': payslip.net_salary,
                    'expense_date': payslip.pay_date,
                    'vendor_name': 'Internal - Payroll',
                    'status': 'approved',  # Auto-approve salary expenses
                    'is_reimbursable': False,  # Salaries are not reimbursable
                    'notes': f'Auto-generated from payslip {payslip.payslip_number}',
                }

                if not dry_run:
                    salary_expense = Expense.objects.create(**salary_expense_data)
                    salary_expense.approved_by = system_user
                    salary_expense.approved_at = timezone.now()
                    salary_expense.save()

                    # Create approval log
                    from expenditure.models import ExpenseApprovalLog
                    ExpenseApprovalLog.objects.create(
                        expense=salary_expense,
                        action='approved',
                        performed_by=system_user,
                        comments='Auto-approved salary expense'
                    )

                total_salary_amount += payslip.net_salary
                created_expenses += 1

                if dry_run:
                    self.stdout.write(f'Would create salary expense: {salary_expense_data["title"]} - KES {salary_expense_data["amount"]}')
                else:
                    self.stdout.write(f'Created salary expense: {salary_expense.expense_number} - KES {salary_expense.amount}')
            else:
                self.stdout.write(f'Salary expense already exists for {employee.full_name} - {target_month}/{target_year}')

            # Create bonus expenses if there are bonuses in the payslip
            if payslip.total_bonuses > 0:
                existing_bonus_expense = Expense.objects.filter(
                    employee=employee,
                    category=bonus_category,
                    expense_date__year=target_year,
                    expense_date__month=target_month,
                    title__icontains='bonus'
                ).first()

                if not existing_bonus_expense:
                    # Get bonus breakdown for description
                    bonus_breakdown = payslip.get_bonus_breakdown()
                    bonus_description = f'Bonus payments for {employee.full_name} (Payslip: {payslip.payslip_number})\n'
                    if bonus_breakdown:
                        bonus_description += 'Breakdown:\n'
                        for bonus in bonus_breakdown:
                            bonus_description += f'- {bonus.get_bonus_type_display()}: KES {bonus.amount} ({bonus.reason})\n'

                    bonus_expense_data = {
                        'employee': employee,
                        'category': bonus_category,
                        'related_payslip': payslip,
                        'title': f'Bonuses - {employee.full_name} - {payslip.pay_period_start.strftime("%B %Y")}',
                        'description': bonus_description,
                        'amount': payslip.total_bonuses,
                        'expense_date': payslip.pay_date,
                        'vendor_name': 'Internal - Payroll',
                        'status': 'approved',  # Auto-approve bonus expenses
                        'is_reimbursable': False,  # Bonuses are not reimbursable
                        'notes': f'Auto-generated from payslip {payslip.payslip_number}',
                    }

                    if not dry_run:
                        bonus_expense = Expense.objects.create(**bonus_expense_data)
                        bonus_expense.approved_by = system_user
                        bonus_expense.approved_at = timezone.now()
                        bonus_expense.save()

                        # Create approval log
                        from expenditure.models import ExpenseApprovalLog
                        ExpenseApprovalLog.objects.create(
                            expense=bonus_expense,
                            action='approved',
                            performed_by=system_user,
                            comments='Auto-approved bonus expense'
                        )

                    total_bonus_amount += payslip.total_bonuses
                    created_expenses += 1

                    if dry_run:
                        self.stdout.write(f'Would create bonus expense: {bonus_expense_data["title"]} - KES {bonus_expense_data["amount"]}')
                    else:
                        self.stdout.write(f'Created bonus expense: {bonus_expense.expense_number} - KES {bonus_expense.amount}')
                else:
                    self.stdout.write(f'Bonus expense already exists for {employee.full_name} - {target_month}/{target_year}')

        # Summary
        self.stdout.write(
            self.style.SUCCESS(
                f'\n{"DRY RUN - " if dry_run else ""}Summary:'
                f'\n- {"Would create" if dry_run else "Created"} {created_expenses} expenses'
                f'\n- Total salary amount: KES {total_salary_amount:,}'
                f'\n- Total bonus amount: KES {total_bonus_amount:,}'
                f'\n- Grand total: KES {total_salary_amount + total_bonus_amount:,}'
            )
        )
