import React, { useState } from 'react';
import { Users, Plus, Trash2, Edit2, Mail } from 'lucide-react';
import { dataAPI } from '../infrastructure/api/data';
import { escapeSoqlValue } from '../infrastructure/api/types';
import { SYSTEM_TABLE_NAMES } from '@nexuscrm/generated-schema';
import { ConfirmationModal } from '@nexuscrm/salesforce-crm-standard-frontend/platform/components/ui';
import { useErrorToast, useSuccessToast } from '@nexuscrm/salesforce-crm-standard-frontend/platform/components/ui';
import { formatApiError } from '@nexuscrm/host-sdk';
import { COMMON_FIELDS } from '../core/constants';
import type { GroupMember, User } from '../types';
import { PowerList, PowerListColumn } from '@nexuscrm/salesforce-crm-standard-frontend/platform/components/ui';
import { Tooltip } from '@nexuscrm/salesforce-crm-standard-frontend/platform/components/ui';
import { Badge } from '@nexuscrm/salesforce-crm-standard-frontend/platform/components/ui';
import { useGroups, useCreateGroup, useDeleteGroup } from '../features/security/groupQueries';
import type { Group } from '../types';

// Sub-components
import { GroupFormModal, GroupFormData } from '../features/admin/components/groups/GroupFormModal';
import { GroupMembersModal } from '../features/admin/components/groups/GroupMembersModal';

export const GroupManager: React.FC = () => {
    const errorToast = useErrorToast();
    const successToast = useSuccessToast();

    const { data: groups = [], isLoading: loading } = useGroups();
    const createGroupMutation = useCreateGroup();
    const deleteGroupMutation = useDeleteGroup();

    const [showCreateModal, setShowCreateModal] = useState(false);
    const [editingGroup, setEditingGroup] = useState<Group | null>(null);
    const [deletingGroup, setDeletingGroup] = useState<Group | null>(null);
    const [managingMembersFor, setManagingMembersFor] = useState<Group | null>(null);
    const [members, setMembers] = useState<GroupMember[]>([]);
    const [availableUsers, setAvailableUsers] = useState<User[]>([]);
    const [memberUsers, setMemberUsers] = useState<User[]>([]);

    const loadMembers = async (groupId: string) => {
        try {
            const membersRecords = await dataAPI.query<GroupMember>({
                objectApiName: SYSTEM_TABLE_NAMES.GROUPMEMBER,
                selectFields: ['Id', 'GroupId', 'UserOrGroupId'],
                filterExpr: `GroupId = '${escapeSoqlValue(groupId)}'`
            });
            setMembers(membersRecords);

            const allUsers = await dataAPI.query<User>({
                objectApiName: SYSTEM_TABLE_NAMES.USER,
                selectFields: ['Id', 'Name', 'Email', 'Username']
            });
            setAvailableUsers(allUsers);

            const memberUserIds = membersRecords.map((m: GroupMember) => m.UserOrGroupId);
            setMemberUsers(allUsers.filter((u: User) => memberUserIds.includes(u[COMMON_FIELDS.ID] as string)));
        } catch (err: unknown) {
            errorToast(`Failed to load group members: ${formatApiError(err).message}`);
        }
    };

    const handleCreate = async (formData: GroupFormData) => {
        try {
            // eslint-disable-next-line @typescript-eslint/no-unused-vars
            const { supportedObjects, ...groupData } = formData;

            const newGroup = await createGroupMutation.mutateAsync(groupData);

            if (formData.type === 'Queue' && formData.supportedObjects && formData.supportedObjects.length > 0) {
                const promises = formData.supportedObjects.map(obj =>
                    dataAPI.createRecord(SYSTEM_TABLE_NAMES.QUEUESOBJECT, {
                        QueueId: newGroup.Id,
                        SobjectType: obj
                    })
                );
                await Promise.all(promises);
            }

            successToast('Group created successfully');
            setShowCreateModal(false);
        } catch (err: unknown) {
            errorToast(`Failed to create group: ${formatApiError(err).message}`);
        }
    };

    const handleUpdate = async (formData: GroupFormData) => {
        if (!editingGroup) return;
        try {
            // eslint-disable-next-line @typescript-eslint/no-unused-vars
            const { supportedObjects, ...groupData } = formData;

            await dataAPI.updateRecord(SYSTEM_TABLE_NAMES.GROUP, editingGroup[COMMON_FIELDS.ID] as string, groupData);

            if (formData.type === 'Queue') {
                interface QueueSobjectResult { Id: string; SobjectType: string; }
                const existing = await dataAPI.query<QueueSobjectResult>({
                    objectApiName: SYSTEM_TABLE_NAMES.QUEUESOBJECT,
                    selectFields: ['Id', 'QueueId', 'SobjectType'],
                    filterExpr: `QueueId = '${escapeSoqlValue(editingGroup[COMMON_FIELDS.ID] as string)}'`
                });

                const existingTypes = existing.map((r) => r.SobjectType);
                const newTypes = formData.supportedObjects || [];

                const toAdd = newTypes.filter(t => !existingTypes.includes(t));
                const toRemove = existing.filter((r) => !newTypes.includes(r.SobjectType));

                await Promise.all(toAdd.map(obj =>
                    dataAPI.createRecord(SYSTEM_TABLE_NAMES.QUEUESOBJECT, {
                        QueueId: editingGroup[COMMON_FIELDS.ID],
                        SobjectType: obj
                    })
                ));

                await Promise.all(toRemove.map((r) =>
                    dataAPI.deleteRecord(SYSTEM_TABLE_NAMES.QUEUESOBJECT, r.Id)
                ));
            }

            successToast('Group updated successfully');
            setEditingGroup(null);
        } catch (err: unknown) {
            errorToast(`Failed to update group: ${formatApiError(err).message}`);
        }
    };

    const handleDelete = async () => {
        if (!deletingGroup) return;
        try {
            await deleteGroupMutation.mutateAsync(deletingGroup[COMMON_FIELDS.ID] as string);
            successToast('Group deleted successfully');
            setDeletingGroup(null);
        } catch (err: unknown) {
            errorToast(`Failed to delete group: ${formatApiError(err).message}`);
        }
    };

    const addMember = async (userId: string) => {
        if (!managingMembersFor) return;
        try {
            await dataAPI.createRecord(SYSTEM_TABLE_NAMES.GROUPMEMBER, {
                GroupId: managingMembersFor[COMMON_FIELDS.ID] as string,
                UserOrGroupId: userId
            });
            successToast('Member added');
            loadMembers(managingMembersFor[COMMON_FIELDS.ID] as string);
        } catch {
            errorToast('Failed to add member');
        }
    };

    const removeMember = async (memberId: string) => {
        try {
            await dataAPI.deleteRecord(SYSTEM_TABLE_NAMES.GROUPMEMBER, memberId);
            successToast('Member removed');
            if (managingMembersFor) {
                loadMembers(managingMembersFor[COMMON_FIELDS.ID] as string);
            }
        } catch {
            errorToast('Failed to remove member');
        }
    };

    const openMembersModal = (group: Group) => {
        setManagingMembersFor(group);
        loadMembers(group[COMMON_FIELDS.ID] as string);
    };

    const groupColumns: PowerListColumn<Group>[] = [
        {
            key: 'Name',
            label: 'Name',
            minWidth: '180px',
            render: (val) => <span className="font-medium text-slate-900 dark:text-white">{val ? String(val) : '—'}</span>,
        },
        {
            key: 'DeveloperName',
            label: 'Developer Name',
            minWidth: '160px',
            render: (val, group) => (
                <span className="font-mono text-xs text-slate-600 dark:text-gray-400">
                    {val ? String(val) : group.Name || '—'}
                </span>
            ),
        },
        {
            key: 'Type',
            label: 'Type',
            minWidth: '100px',
            render: (val) => (
                <Badge variant={String(val) === 'Queue' ? 'info' : 'neutral'}>
                    {val ? String(val) : '—'}
                </Badge>
            ),
        },
        {
            key: 'Email',
            label: 'Email',
            minWidth: '160px',
            render: (val) => val ? (
                <span className="flex items-center gap-1 text-slate-500 dark:text-gray-400">
                    <Mail size={14} />
                    {String(val)}
                </span>
            ) : <span className="text-gray-400">—</span>,
        },
    ];

    const renderGroupActions = (group: Group) => (
        <div className="flex items-center justify-end gap-1">
            <Tooltip content="Members" position="top">
                <button
                    onClick={() => openMembersModal(group)}
                    className="p-1.5 text-gray-400 hover:text-teal-500 hover:bg-teal-50 dark:hover:bg-teal-900/20 rounded-lg transition-colors"
                >
                    <Users size={16} />
                </button>
            </Tooltip>
            <Tooltip content="Edit" position="top">
                <button
                    onClick={() => setEditingGroup(group)}
                    className="p-1.5 text-gray-400 hover:text-blue-500 hover:bg-blue-50 dark:hover:bg-blue-900/20 rounded-lg transition-colors"
                >
                    <Edit2 size={16} />
                </button>
            </Tooltip>
            <Tooltip content="Delete" position="top">
                <button
                    onClick={() => setDeletingGroup(group)}
                    className="p-1.5 text-gray-400 hover:text-red-500 hover:bg-red-50 dark:hover:bg-red-900/20 rounded-lg transition-colors"
                >
                    <Trash2 size={16} />
                </button>
            </Tooltip>
        </div>
    );

    return (
        <div className="max-w-7xl mx-auto p-6">
            <div className="flex items-center justify-between mb-8">
                <div className="flex items-center gap-4">
                    <div className="p-3 bg-teal-100 rounded-lg">
                        <Users className="text-teal-600" size={32} />
                    </div>
                    <div>
                        <h1 className="text-2xl font-bold text-slate-800">Groups & Queues</h1>
                        <p className="text-slate-500">Manage user groups for record ownership and collaboration.</p>
                    </div>
                </div>
                <button
                    onClick={() => setShowCreateModal(true)}
                    className="flex items-center gap-2 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 font-medium shadow-sm transition-colors"
                >
                    <Plus size={18} />
                    New Group
                </button>
            </div>

            <PowerList<Group>
                data={groups}
                columns={groupColumns}
                loading={loading}
                rowKey={(g) => g[COMMON_FIELDS.ID] as string}
                searchable
                searchPlaceholder="Search groups..."
                defaultSort={{ key: 'Name', direction: 'asc' }}
                emptyIcon={<Users className="w-12 h-12" />}
                emptyTitle="No Groups Yet"
                emptyMessage="Create your first group to manage record ownership."
                emptyAction={{ label: 'New Group', onClick: () => setShowCreateModal(true) }}
                actions={renderGroupActions}
                ariaLabel="Groups list"
            />

            {/* Create/Edit Modal */}
            <GroupFormModal
                isOpen={showCreateModal || !!editingGroup}
                groupId={editingGroup ? editingGroup[COMMON_FIELDS.ID] as string : undefined}
                initialData={editingGroup ? {
                    name: editingGroup.Name,
                    label: editingGroup.Name,
                    type: editingGroup.Type as 'Queue' | 'Regular',
                    email: editingGroup.Email || ''
                } : null}
                isEditing={!!editingGroup}
                onClose={() => {
                    setShowCreateModal(false);
                    setEditingGroup(null);
                }}
                onSave={editingGroup ? handleUpdate : handleCreate}
            />

            {/* Members Modal */}
            <GroupMembersModal
                group={managingMembersFor}
                members={members}
                availableUsers={availableUsers}
                memberUsers={memberUsers}
                onClose={() => setManagingMembersFor(null)}
                onAddMember={addMember}
                onRemoveMember={removeMember}
            />

            {/* Delete Confirmation */}
            <ConfirmationModal
                isOpen={!!deletingGroup}
                onClose={() => setDeletingGroup(null)}
                onConfirm={handleDelete}
                title="Delete Group"
                message={`Are you sure you want to delete "${deletingGroup?.Name}"? This will also remove all member associations.`}
                confirmLabel="Delete"
                variant="danger"
            />
        </div>
    );
};
