"""
Management command: load_chat_data

بارگذاری داده‌های آزمایشی سرویس چت.
کارمندان HRM با اکانت کاربری را به عنوان شرکت‌کنندگان چت استفاده می‌کند.
"""
import random
from datetime import timedelta

from django.core.management.base import BaseCommand
from django.utils import timezone

from apps.core.auth.models import User
from apps.core.permission.models import Role, UserRole
from apps.core.tenant.models import Tenant
from apps.services.chat.models import (
    Channel,
    ChannelMember,
    ChannelType,
    ChannelVisibility,
    MemberRole,
    MemberStatus,
    Message,
    MessageType,
    UserPresence,
    PresenceStatus,
)


def _get_hrm_users(tenant, limit=15):
    """
    ابتدا کارمندان HRM با user لینک‌شده را برمی‌گرداند.
    اگر کافی نبود، از کاربران فعال سیستم تکمیل می‌شود.
    """
    hrm_user_ids = []
    try:
        from modules.hrm.backend.infrastructure.persistence.models import EmployeeModel
        hrm_user_ids = list(
            EmployeeModel.objects.filter(
                tenant=tenant,
                user__isnull=False,
                user__is_active=True,
            ).values_list('user_id', flat=True)[:limit]
        )
    except Exception:
        pass

    if len(hrm_user_ids) < 2:
        hrm_user_ids = list(
            User.objects.filter(tenant=tenant, is_active=True)
            .values_list('id', flat=True)[:limit]
        )

    return list(User.objects.filter(id__in=hrm_user_ids).select_related('tenant'))


class Command(BaseCommand):
    help = 'Load chat test data with HRM employees'

    def add_arguments(self, parser):
        parser.add_argument(
            '--tenant',
            type=str,
            default='public',
            help='schema_name of the tenant (default: public)',
        )
        parser.add_argument(
            '--clear',
            action='store_true',
            help='Clear previous data',
        )
        parser.add_argument(
            '--assign-roles',
            action='store_true',
            default=True,
            dest='assign_roles',
            help='Assign manager role to users (default: enabled)',
        )
        parser.add_argument(
            '--no-assign-roles',
            action='store_false',
            dest='assign_roles',
            help='Do not assign roles to users',
        )

    def handle(self, *args, **options):
        schema = options['tenant']
        try:
            tenant = Tenant.objects.get(schema_name=schema)
        except Tenant.DoesNotExist:
            self.stderr.write(self.style.ERROR(f'Tenant "{schema}" not found.'))
            return

        if options.get('clear'):
            Message.objects.filter(tenant=tenant).delete()
            ChannelMember.objects.filter(tenant=tenant).delete()
            Channel.objects.filter(tenant=tenant).delete()
            UserPresence.objects.filter(tenant=tenant).delete()
            self.stdout.write('  \u2714 Previous data cleared')

        users = _get_hrm_users(tenant, limit=15)
        if len(users) < 2:
            self.stderr.write(self.style.ERROR('At least 2 active users required.'))
            return

        try:
            from modules.hrm.backend.infrastructure.persistence.models import EmployeeModel
            hrm_count = EmployeeModel.objects.filter(tenant=tenant, user__isnull=False).count()
            source = f'HRM ({hrm_count} employees)' if hrm_count else 'System users'
        except Exception:
            source = 'System users'

        self.stdout.write(f'Using {len(users)} users [{source}] for tenant "{schema}"')
        for u in users[:5]:
            self.stdout.write(f'  - {u.get_full_name() or u.email}')
        if len(users) > 5:
            self.stdout.write(f'  ... and {len(users) - 5} more')

        # -- Assign manager role --
        if options.get('assign_roles'):
            try:
                manager_role = Role.objects.filter(slug='manager', tenant=tenant).first()
                if manager_role:
                    assigned = 0
                    for u in users:
                        if not u.is_superuser:
                            _, created = UserRole.objects.get_or_create(
                                user=u,
                                role=manager_role,
                                organizational_unit=None,
                                defaults={},
                            )
                            if created:
                                assigned += 1
                    self.stdout.write(f'  \u2714 Manager role assigned to {assigned} users')
                else:
                    self.stdout.write(self.style.WARNING(
                        '  \u26a0 Manager role not found - run seed_permissions first'
                    ))
            except Exception as exc:
                self.stdout.write(self.style.WARNING(f'  \u26a0 Role assignment error: {exc}'))

            try:
                from django.core.cache import cache
                for u in users:
                    cache.delete(f'user_all_perms:{u.id}')
            except Exception:
                pass

        # -- Channels --
        now = timezone.now()

        channels_data = [
            {
                'name': '\u067e\u0634\u062a\u06cc\u0628\u0627\u0646\u06cc \u0641\u0646\u06cc',
                'channel_type': ChannelType.GROUP,
                'visibility': ChannelVisibility.PRIVATE,
                'description': '\u06a9\u0627\u0646\u0627\u0644 \u067e\u0634\u062a\u06cc\u0628\u0627\u0646\u06cc \u0648 \u0631\u0641\u0639 \u0645\u0634\u06a9\u0644\u0627\u062a \u0641\u0646\u06cc',
            },
            {
                'name': '\u0627\u0637\u0644\u0627\u0639\u06cc\u0647\u200c\u0647\u0627\u06cc \u0639\u0645\u0648\u0645\u06cc',
                'channel_type': ChannelType.PUBLIC,
                'visibility': ChannelVisibility.PUBLIC,
                'description': '\u0627\u062e\u0628\u0627\u0631 \u0648 \u0627\u0637\u0644\u0627\u0639\u06cc\u0647\u200c\u0647\u0627\u06cc \u0633\u0627\u0632\u0645\u0627\u0646\u06cc',
            },
            {
                'name': '\u062a\u06cc\u0645 \u062a\u0648\u0633\u0639\u0647',
                'channel_type': ChannelType.GROUP,
                'visibility': ChannelVisibility.PRIVATE,
                'description': '\u0647\u0645\u0627\u0647\u0646\u06af\u06cc \u062a\u06cc\u0645 \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0646\u0648\u06cc\u0633\u0627\u0646',
            },
            {
                'name': '\u0645\u0646\u0627\u0628\u0639 \u0627\u0646\u0633\u0627\u0646\u06cc',
                'channel_type': ChannelType.GROUP,
                'visibility': ChannelVisibility.PRIVATE,
                'description': '\u06a9\u0627\u0646\u0627\u0644 \u0648\u0627\u062d\u062f \u0645\u0646\u0627\u0628\u0639 \u0627\u0646\u0633\u0627\u0646\u06cc',
            },
            {
                'name': '\u067e\u0631\u0648\u0698\u0647 \u0646\u06a9\u0633\u0627',
                'channel_type': ChannelType.PROJECT,
                'visibility': ChannelVisibility.PROJECT,
                'description': '\u06a9\u0627\u0646\u0627\u0644 \u067e\u0631\u0648\u0698\u0647 \u0646\u06a9\u0633\u0627 \u2014 \u0647\u0645\u0627\u0647\u0646\u06af\u06cc \u0648 \u067e\u06cc\u0634\u0631\u0641\u062a',
            },
        ]

        created_channels = []
        for cd in channels_data:
            ch, created = Channel.objects.get_or_create(
                tenant=tenant,
                name=cd['name'],
                defaults={
                    'channel_type': cd['channel_type'],
                    'visibility': cd['visibility'],
                    'description': cd['description'],
                    'created_by': users[0],
                    'last_message_at': now,
                },
            )
            if created:
                self.stdout.write(f'  \u2714 Channel: {ch.name}')
            created_channels.append(ch)

        # -- Members --
        for ch in created_channels:
            ChannelMember.objects.get_or_create(
                tenant=tenant,
                channel=ch,
                user=users[0],
                defaults={'role': MemberRole.OWNER, 'status': MemberStatus.ACTIVE},
            )
            available = users[1:]
            member_users = random.sample(available, min(len(available), 6))
            for u in member_users:
                ChannelMember.objects.get_or_create(
                    tenant=tenant,
                    channel=ch,
                    user=u,
                    defaults={'role': MemberRole.MEMBER, 'status': MemberStatus.ACTIVE},
                )

        self.stdout.write('  \u2714 Members added')

        # -- Direct Messages (DM) --
        dm_count = 0
        pairs = [(i, j) for i in range(min(len(users), 5)) for j in range(i + 1, min(len(users), 5))]
        for u1_idx, u2_idx in pairs[:6]:
            u1, u2 = users[u1_idx], users[u2_idx]
            uid1, uid2 = min(u1.id, u2.id), max(u1.id, u2.id)
            dm, created = Channel.objects.get_or_create(
                tenant=tenant,
                channel_type=ChannelType.DIRECT,
                name=f'DM-{uid1}-{uid2}',
                defaults={
                    'visibility': ChannelVisibility.PRIVATE,
                    'max_members': 2,
                    'created_by': u1,
                    'last_message_at': now,
                },
            )
            if created:
                for u in (u1, u2):
                    ChannelMember.objects.get_or_create(
                        tenant=tenant, channel=dm, user=u,
                        defaults={'role': MemberRole.MEMBER, 'status': MemberStatus.ACTIVE},
                    )
                u1_name = u1.get_full_name() or u1.email.split('@')[0]
                u2_name = u2.get_full_name() or u2.email.split('@')[0]
                self.stdout.write(f'  \u2714 DM: {u1_name} \u2194 {u2_name}')
                dm_count += 1
            created_channels.append(dm)

        # -- Messages --
        sample_messages = [
            '\u0633\u0644\u0627\u0645\u060c \u0648\u0642\u062a \u0628\u062e\u06cc\u0631 \U0001f44b',
            '\u0645\u0645\u0646\u0648\u0646\u060c \u062d\u0627\u0644\u062a \u062e\u0648\u0628\u0647\u061f',
            '\u0622\u06cc\u0627 \u062c\u0644\u0633\u0647 \u0641\u0631\u062f\u0627 \u0628\u0631\u0642\u0631\u0627\u0631\u0647\u061f',
            '\u0628\u0644\u0647\u060c \u0633\u0627\u0639\u062a \u06f1\u06f0 \u0635\u0628\u062d.',
            '\u062e\u0633\u062a\u0647 \u0646\u0628\u0627\u0634\u06cc\u062f \U0001f64f',
            '\u06af\u0632\u0627\u0631\u0634 \u0622\u0645\u0627\u062f\u0647 \u0634\u062f.',
            '\u0641\u0627\u06cc\u0644 \u0631\u0648 \u0641\u0631\u0633\u062a\u0627\u062f\u0645.',
            '\u0644\u0637\u0641\u0627\u064b \u062a\u0623\u06cc\u06cc\u062f \u06a9\u0646\u06cc\u062f.',
            '\u0628\u0627\u0634\u0647\u060c \u0627\u0646\u062c\u0627\u0645 \u0645\u06cc\u062f\u0645.',
            '\u0645\u0634\u06a9\u0644 \u062d\u0644 \u0634\u062f \u2705',
            '\u062f\u0645\u062a\u0648\u0646 \u06af\u0631\u0645 \U0001f339',
            '\u0644\u0637\u0641\u0627\u064b \u0628\u0631\u0631\u0633\u06cc \u06a9\u0646\u06cc\u062f.',
            '\u0645\u0645\u0646\u0648\u0646 \u0627\u0632 \u0647\u0645\u06a9\u0627\u0631\u06cc\u062a\u0648\u0646.',
            '\u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0622\u067e\u062f\u06cc\u062a \u0634\u062f.',
            '\u06a9\u0627\u0631 \u062e\u0648\u0628\u06cc \u0628\u0648\u062f! \U0001f44d',
            '\u0622\u06cc\u0627 \u0628\u0627\u06af \u062b\u0628\u062a \u0634\u062f\u0647\u061f',
            '\u0628\u0644\u0647\u060c \u062a\u06cc\u06a9\u062a \u0632\u062f\u0647 \u0634\u062f.',
            '\u0627\u0633\u067e\u0631\u06cc\u0646\u062a \u0628\u0639\u062f\u06cc \u0686\u06cc \u062f\u0627\u0631\u06cc\u0645\u061f',
            '\u0628\u06a9\u200c\u0644\u0627\u06af \u0631\u0648 \u0645\u0631\u0648\u0631 \u06a9\u0646\u06cc\u0645.',
            '\u062f\u0645\u0648\u06cc \u067e\u0646\u062c\u0634\u0646\u0628\u0647 \u06cc\u0627\u062f\u062a\u0648\u0646 \u0628\u0627\u0634\u0647.',
            '\u0633\u06cc\u0633\u062a\u0645 \u0622\u067e\u062f\u06cc\u062a \u0634\u062f\u060c \u0644\u0637\u0641\u0627\u064b \u062a\u0633\u062a \u06a9\u0646\u06cc\u062f.',
            '\u0646\u062a\u0627\u06cc\u062c \u0627\u0631\u0632\u06cc\u0627\u0628\u06cc \u0622\u0645\u0627\u062f\u0647\u200c\u0633\u062a.',
            '\u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0645\u0631\u062e\u0635\u06cc \u062b\u0628\u062a \u0634\u062f.',
        ]

        msg_count = 0
        for ch in created_channels:
            active_members = list(
                ChannelMember.objects.filter(
                    channel=ch, status=MemberStatus.ACTIVE,
                ).values_list('user', flat=True)
            )
            member_users = list(User.objects.filter(id__in=active_members))
            if not member_users:
                continue

            num_messages = random.randint(8, 20)
            for _ in range(num_messages):
                sender = random.choice(member_users)
                content = random.choice(sample_messages)
                ts = now - timedelta(
                    hours=random.randint(0, 72),
                    minutes=random.randint(0, 59),
                    seconds=random.randint(0, 59),
                )
                Message.objects.create(
                    tenant=tenant,
                    channel=ch,
                    sender=sender,
                    message_type=MessageType.TEXT,
                    content=content,
                    created_at=ts,
                )
                msg_count += 1

        self.stdout.write(f'  \u2714 Messages: {msg_count}')

        # -- Presence --
        statuses = [
            PresenceStatus.ONLINE,
            PresenceStatus.ONLINE,
            PresenceStatus.AWAY,
            PresenceStatus.BUSY,
            PresenceStatus.OFFLINE,
        ]
        custom_statuses = [
            '',
            '\u0645\u0634\u063a\u0648\u0644 \u06a9\u0627\u0631',
            '\u062c\u0644\u0633\u0647',
            '\u0646\u0647\u0627\u0631',
            '\u062f\u0648\u0631 \u0627\u0632 \u0645\u06cc\u0632',
            '\u0631\u0648\u06cc \u067e\u0631\u0648\u0698\u0647 \u0646\u06a9\u0633\u0627',
        ]

        for u in users:
            UserPresence.objects.update_or_create(
                tenant=tenant,
                user=u,
                defaults={
                    'status': random.choice(statuses),
                    'custom_status': random.choice(custom_statuses),
                    'last_seen': now - timedelta(minutes=random.randint(0, 60)),
                },
            )

        self.stdout.write(f'  \u2714 Presence set for {len(users)} users')

        group_count = len([c for c in created_channels if c.channel_type != ChannelType.DIRECT])
        self.stdout.write(self.style.SUCCESS(
            f'\n\u2705 Chat test data loaded:\n'
            f'   {group_count} group/public channels\n'
            f'   {dm_count} direct messages\n'
            f'   {msg_count} messages\n'
            f'   {len(users)} presence records\n'
            f'   Source: {source}'
        ))