from django.core.management.base import BaseCommand
from django.utils import timezone
from datetime import date, timedelta, datetime
from decimal import Decimal
import random

from accounts.models import CustomUser
from members.models import Member
from departments.models import Department
from events.models import Event
from finance.models import (
    Contribution, ContributionType,
    PaymentMethod, MpesaTransaction
)


class Command(BaseCommand):
    help = 'Seed database with realistic demo data'

    def handle(self, *args, **options):
        self.stdout.write('Seeding demo data...')
        self.create_contribution_types()
        self.create_payment_methods()
        self.create_departments()
        self.create_staff_users()
        self.create_members()
        self.create_events()
        self.create_contributions()
        self.stdout.write(
            self.style.SUCCESS('Demo data seeded successfully!')
        )

    # ── Contribution Types ──────────────────────────────────

    def create_contribution_types(self):
        types = [
            {'name': 'Tithe', 'keyword': 'tithe'},
            {'name': 'Offering', 'keyword': 'offering'},
            {'name': 'Seed', 'keyword': 'seed'},
            {'name': 'Building Fund', 'keyword': 'building'},
            {'name': 'Thanksgiving', 'keyword': 'thanksgiving'},
            {'name': 'Missions', 'keyword': 'missions'},
        ]
        for t in types:
            ContributionType.objects.get_or_create(
                name=t['name'],
                defaults={'keyword': t['keyword']}
            )
        self.stdout.write(f'  Created {len(types)} contribution types')

    # ── Payment Methods ─────────────────────────────────────

    def create_payment_methods(self):
        methods = [
            'Cash',
            'M-Pesa STK',
            'M-Pesa Paybill',
            'Bank Transfer',
            'Cheque',
        ]
        for m in methods:
            PaymentMethod.objects.get_or_create(name=m)
        self.stdout.write(f'  Created {len(methods)} payment methods')

    # ── Departments ─────────────────────────────────────────

    def create_departments(self):
        departments = [
            {
                'name': 'Worship & Music',
                'description': 'Leads the congregation in worship through music and praise',
            },
            {
                'name': 'Ushering & Protocol',
                'description': 'Welcomes and guides members and visitors during services',
            },
            {
                'name': 'Children Ministry',
                'description': 'Nurtures the spiritual growth of children aged 3-12',
            },
            {
                'name': 'Youth Ministry',
                'description': 'Engages and mentors teenagers and young adults aged 13-35',
            },
            {
                'name': 'Prayer & Intercession',
                'description': 'Leads corporate prayer and intercession for the church',
            },
            {
                'name': 'Evangelism & Outreach',
                'description': 'Spreads the gospel and conducts community outreach programs',
            },
            {
                'name': 'Media & Communications',
                'description': 'Manages church media, live streaming, and communications',
            },
            {
                'name': 'Women of Grace',
                'description': 'Empowers and fellowships with women in the church',
            },
        ]
        for d in departments:
            Department.objects.get_or_create(
                name=d['name'],
                defaults={'description': d['description']}
            )
        self.stdout.write(f'  Created {len(departments)} departments')

    # ── Staff Users ─────────────────────────────────────────

    def create_staff_users(self):
        staff = [
            {
                'username': 'pastor.james',
                'first_name': 'James',
                'last_name': 'Mwangi',
                'email': 'pastor@cfcchurch.com',
                'role': 'pastor',
                'phone': '0722000001',
                'password': 'CFC@2024',
            },
            {
                'username': 'finance.officer',
                'first_name': 'Grace',
                'last_name': 'Wanjiku',
                'email': 'finance@cfcchurch.com',
                'role': 'finance_officer',
                'phone': '0722000002',
                'password': 'CFC@2024',
            },
            {
                'username': 'secretary',
                'first_name': 'Mary',
                'last_name': 'Achieng',
                'email': 'secretary@cfcchurch.com',
                'role': 'secretary',
                'phone': '0722000003',
                'password': 'CFC@2024',
            },
        ]
        for s in staff:
            if not CustomUser.objects.filter(username=s['username']).exists():
                CustomUser.objects.create_user(
                    username=s['username'],
                    first_name=s['first_name'],
                    last_name=s['last_name'],
                    email=s['email'],
                    role=s['role'],
                    phone=s['phone'],
                    password=s['password'],
                )
        self.stdout.write(f'  Created {len(staff)} staff users')

    # ── Members ─────────────────────────────────────────────

    def create_members(self):
        first_names_m = [
            'James', 'John', 'Peter', 'Paul', 'David',
            'Daniel', 'Joseph', 'Samuel', 'Michael', 'Emmanuel',
            'Kevin', 'Brian', 'Eric', 'Dennis', 'George',
            'Patrick', 'Francis', 'Anthony', 'Charles', 'Robert',
        ]
        first_names_f = [
            'Mary', 'Grace', 'Faith', 'Hope', 'Joy',
            'Esther', 'Ruth', 'Sarah', 'Hannah', 'Miriam',
            'Agnes', 'Betty', 'Caroline', 'Diana', 'Elizabeth',
            'Florence', 'Gloria', 'Helen', 'Irene', 'Janet',
        ]
        last_names = [
            'Kamau', 'Wanjiku', 'Mwangi', 'Njoroge', 'Kariuki',
            'Ochieng', 'Achieng', 'Otieno', 'Waweru', 'Gitau',
            'Mutua', 'Muthoni', 'Kimani', 'Njuguna', 'Gichuki',
            'Odhiambo', 'Adhiambo', 'Auma', 'Awino', 'Anyango',
            'Makau', 'Musyoka', 'Muthoka', 'Ndolo', 'Kilonzo',
        ]

        departments = list(Department.objects.all())
        admin_user = CustomUser.objects.filter(
            role='super_admin'
        ).first()

        created = 0
        for i in range(1, 51):
            gender = random.choice(['M', 'F'])
            if gender == 'M':
                first = random.choice(first_names_m)
            else:
                first = random.choice(first_names_f)
            last = random.choice(last_names)

            member_id = f"CFC{str(i).zfill(3)}"

            if Member.objects.filter(member_id=member_id).exists():
                continue

            # Generate phone — unique
            phone = f"07{random.randint(10, 99)}{random.randint(100000, 999999)}"
            while Member.objects.filter(phone=phone).exists():
                phone = f"07{random.randint(10, 99)}{random.randint(100000, 999999)}"

            dob = date(
                random.randint(1960, 2000),
                random.randint(1, 12),
                random.randint(1, 28)
            )

            joined = date(
                random.randint(2018, 2023),
                random.randint(1, 12),
                random.randint(1, 28)
            )

            status = random.choices(
                ['active', 'active', 'active', 'inactive', 'transferred'],
                weights=[70, 70, 70, 15, 5]
            )[0]

            Member.objects.create(
                member_id=member_id,
                full_name=f"{first} {last}",
                phone=phone,
                email=f"{first.lower()}.{last.lower()}@gmail.com"
                if random.random() > 0.4 else None,
                gender=gender,
                date_of_birth=dob,
                address=random.choice([
                    'Nairobi, Kenya',
                    'Westlands, Nairobi',
                    'Kasarani, Nairobi',
                    'Embakasi, Nairobi',
                    'Ruiru, Kiambu',
                    'Thika, Kiambu',
                    'Kikuyu, Kiambu',
                    'Machakos Town',
                    'Kitengela, Kajiado',
                    'Rongai, Kajiado',
                ]),
                department=random.choice(departments) if departments else None,
                membership_status=status,
                date_joined=joined,
                created_by=admin_user,
            )
            created += 1

        self.stdout.write(f'  Created {created} members')

    # ── Events ──────────────────────────────────────────────

    def create_events(self):
        departments = list(Department.objects.all())
        events = [
            {
                'title': 'Sunday Worship Service',
                'description': 'Join us every Sunday for a powerful time of worship, the Word, and fellowship. All are welcome.',
                'event_type': 'sunday_service',
                'location': 'Main Sanctuary, CFC Church',
                'start_date': timezone.now() + timedelta(days=3),
                'end_date': timezone.now() + timedelta(days=3, hours=3),
                'organizer': 'Pastor James Mwangi',
            },
            {
                'title': 'Annual Missions Conference 2024',
                'description': 'A three-day conference focused on global missions and evangelism. Guest speakers from across Africa.',
                'event_type': 'conference',
                'location': 'CFC Church Auditorium',
                'start_date': timezone.now() + timedelta(days=14),
                'end_date': timezone.now() + timedelta(days=17),
                'organizer': 'Evangelism & Outreach Department',
            },
            {
                'title': 'Friday Night Kesha',
                'description': 'An all-night prayer and worship service. Come ready to seek God through the night.',
                'event_type': 'kesha',
                'location': 'Main Sanctuary, CFC Church',
                'start_date': timezone.now() + timedelta(days=7),
                'end_date': timezone.now() + timedelta(days=8, hours=6),
                'organizer': 'Prayer & Intercession Department',
            },
            {
                'title': 'Wednesday Bible Study',
                'description': 'Deep dive into the book of Romans. Bring your Bible and a notebook.',
                'event_type': 'bible_study',
                'location': 'Fellowship Hall',
                'start_date': timezone.now() + timedelta(days=5),
                'end_date': timezone.now() + timedelta(days=5, hours=2),
                'organizer': 'Pastor James Mwangi',
            },
            {
                'title': 'Youth Annual Retreat',
                'description': 'A weekend retreat for youth aged 13-35. Theme: Rising Higher. Location: Brackenhurst Conference Centre.',
                'event_type': 'special_event',
                'location': 'Brackenhurst, Limuru',
                'start_date': timezone.now() + timedelta(days=21),
                'end_date': timezone.now() + timedelta(days=23),
                'organizer': 'Youth Ministry',
            },
            {
                'title': 'Women of Grace Fellowship',
                'description': 'Monthly fellowship for women. This month\'s theme: Walking in Purpose.',
                'event_type': 'special_event',
                'location': 'Fellowship Hall',
                'start_date': timezone.now() + timedelta(days=10),
                'end_date': timezone.now() + timedelta(days=10, hours=3),
                'organizer': 'Women of Grace Department',
            },
            {
                'title': 'Children Sunday School Anniversary',
                'description': 'Celebrating 10 years of CFC Children Ministry. A special program by the children.',
                'event_type': 'special_event',
                'location': 'Main Sanctuary',
                'start_date': timezone.now() + timedelta(days=28),
                'end_date': timezone.now() + timedelta(days=28, hours=4),
                'organizer': 'Children Ministry',
            },
            {
                'title': 'Community Outreach — Mathare',
                'description': 'Monthly community outreach. We will be distributing food, clothing, and sharing the gospel.',
                'event_type': 'special_event',
                'location': 'Mathare Valley, Nairobi',
                'start_date': timezone.now() + timedelta(days=18),
                'end_date': timezone.now() + timedelta(days=18, hours=6),
                'organizer': 'Evangelism & Outreach Department',
            },
        ]

        for e in events:
            dept = None
            if departments:
                dept = random.choice(departments)
            Event.objects.get_or_create(
                title=e['title'],
                defaults={
                    **e,
                    'department': dept,
                    'is_active': True,
                }
            )
        self.stdout.write(f'  Created {len(events)} events')

    # ── Contributions ───────────────────────────────────────

    def create_contributions(self):
        members = list(Member.objects.filter(membership_status='active'))
        types = list(ContributionType.objects.all())
        methods = list(PaymentMethod.objects.all())

        if not members or not types or not methods:
            self.stdout.write('  Skipping contributions — missing data')
            return

        tithe = ContributionType.objects.filter(name='Tithe').first()
        offering = ContributionType.objects.filter(name='Offering').first()
        mpesa_stk = PaymentMethod.objects.filter(name='M-Pesa STK').first()
        mpesa_c2b = PaymentMethod.objects.filter(name='M-Pesa Paybill').first()
        cash = PaymentMethod.objects.filter(name='Cash').first()

        created = 0
        today = date.today()

        # Generate contributions for last 6 months
        for month_offset in range(6):
            month_date = today.replace(day=1) - timedelta(
                days=month_offset * 30
            )

            # Each active member contributes 1-3 times per month
            for member in random.sample(members, min(40, len(members))):
                num_contributions = random.randint(1, 3)

                for _ in range(num_contributions):
                    contrib_date = month_date + timedelta(
                        days=random.randint(0, 27)
                    )
                    if contrib_date > today:
                        contrib_date = today

                    # Determine type and amount
                    contrib_type = random.choices(
                        types,
                        weights=[40, 30, 10, 10, 5, 5][:len(types)]
                    )[0]

                    if contrib_type.name == 'Tithe':
                        amount = Decimal(
                            random.choice([
                                1000, 1500, 2000, 2500, 3000,
                                3500, 4000, 5000, 7500, 10000
                            ])
                        )
                    elif contrib_type.name == 'Building Fund':
                        amount = Decimal(
                            random.choice([500, 1000, 2000, 5000])
                        )
                    else:
                        amount = Decimal(
                            random.choice([
                                200, 300, 500, 700, 1000, 1500
                            ])
                        )

                    # Determine payment method and source
                    method_choice = random.choices(
                        ['stk', 'c2b', 'cash'],
                        weights=[40, 30, 30]
                    )[0]

                    if method_choice == 'stk' and mpesa_stk:
                        method = mpesa_stk
                        source = 'STK'
                        receipt = f"QHG{random.randint(100000000, 999999999)}"
                    elif method_choice == 'c2b' and mpesa_c2b:
                        method = mpesa_c2b
                        source = 'C2B'
                        receipt = f"RKL{random.randint(100000000, 999999999)}"
                    else:
                        method = cash or methods[0]
                        source = 'CASH'
                        receipt = None

                    Contribution.objects.create(
                        member=member,
                        amount=amount,
                        contribution_type=contrib_type,
                        payment_method=method,
                        source=source,
                        status='completed',
                        date=contrib_date,
                        mpesa_receipt=receipt,
                        phone_number=member.phone if receipt else '',
                        sms_sent=bool(receipt),
                        notes='',
                    )
                    created += 1

        self.stdout.write(f'  Created {created} contributions')