/**
 * Widget Assignment Component
 * Allows assigning widgets to a chatbot
 * @since 1.1.0
 */

import { useState, useMemo } from 'react'
import { t } from '@/lib/i18n'
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import { useNavigate } from 'react-router-dom'
import { 
    Plus, 
    Trash2, 
    FormInput, 
    MessageCircle, 
    Phone, 
    Calendar, 
    Ticket, 
    Image, 
    Youtube,
    User,
    X,
    Loader2,
    Puzzle,
    Pencil
} from 'lucide-react'
import { widgetsApi } from '@/api/widgets'
import { useWidgets } from '@/hooks/useWidgets'
import type { CustomWidget, FormField } from '@/types/widget'
import { isWidgetFullyConfigured, WIDGET_CONFIG_HINTS } from '@/types/widget'

interface WidgetAssignmentProps {
    botId: number
    /** Controlled mode: when provided, use these IDs instead of fetching from API */
    controlledAssignedIds?: number[]
    /** Controlled mode: callback when user changes assignments */
    onControlledChange?: (ids: number[]) => void
}

// Widget type icons
const typeIcons: Record<string, React.ComponentType<{ className?: string }>> = {
    form: FormInput,
    whatsapp: MessageCircle,
    calendar_call: Phone, // backward compat for existing widgets
    calendar_meeting: Calendar,
    coupon: Ticket,
    gallery: Image,
    youtube: Youtube,
    contact_card: User,
}

// Widget type labels
const typeLabels: Record<string, string> = {
    form: t('Form'),
    whatsapp: t('WhatsApp'),
    calendar_call: t('Calendar'), // backward compat
    calendar_meeting: t('Calendar'),
    coupon: t('Coupon'),
    gallery: t('Gallery'),
    youtube: t('YouTube'),
    contact_card: t('Contact Card'),
}

export function WidgetAssignment({ botId, controlledAssignedIds, onControlledChange }: WidgetAssignmentProps) {
    const queryClient = useQueryClient()
    const navigate = useNavigate()
    const [showAddWidget, setShowAddWidget] = useState(false)

    const isControlled = controlledAssignedIds !== undefined && onControlledChange !== undefined

    // Fetch all widgets (filtered by current admin language)
    const { data: allWidgetsData, isLoading: isLoadingAll } = useWidgets(1, 100)

    // Fetch widgets assigned to this bot (only used in uncontrolled mode)
    const { data: assignedWidgetsData, isLoading: isLoadingAssigned } = useQuery({
        queryKey: ['widgets', 'for-chatbot', botId],
        queryFn: () => widgetsApi.getWidgetsForChatbot(botId),
        enabled: !!botId && !isControlled,
    })

    // Assign widget mutation (only used in uncontrolled mode)
    const assignMutation = useMutation({
        mutationFn: (widgetId: number) => widgetsApi.assignToChatbot(widgetId, botId),
        onSuccess: () => {
            queryClient.invalidateQueries({ queryKey: ['widgets', 'for-chatbot', botId] })
            setShowAddWidget(false)
        },
    })

    // Unassign widget mutation with optimistic update for instant feedback (only used in uncontrolled mode)
    const unassignMutation = useMutation({
        mutationFn: (widgetId: number) => widgetsApi.unassignFromChatbot(widgetId, botId),
        
        // Optimistic update - remove immediately from UI
        onMutate: async (widgetId) => {
            // Cancel any outgoing refetches
            await queryClient.cancelQueries({ queryKey: ['widgets', 'for-chatbot', botId] })
            
            // Snapshot the previous value
            const previousWidgets = queryClient.getQueryData(['widgets', 'for-chatbot', botId])
            
            // Optimistically update to the new value
            queryClient.setQueryData(['widgets', 'for-chatbot', botId], (old: { data?: { widgets?: CustomWidget[] } } | undefined) => {
                if (!old?.data?.widgets) return old
                return {
                    ...old,
                    data: {
                        ...old.data,
                        widgets: old.data.widgets.filter((w: CustomWidget) => w.id !== widgetId)
                    }
                }
            })
            
            return { previousWidgets }
        },
        
        // If the mutation fails, use the context returned from onMutate to roll back
        onError: (_err, _widgetId, context) => {
            if (context?.previousWidgets) {
                queryClient.setQueryData(['widgets', 'for-chatbot', botId], context.previousWidgets)
            }
        },
        
        // Always refetch after error or success to ensure consistency
        onSettled: () => {
            queryClient.invalidateQueries({ queryKey: ['widgets', 'for-chatbot', botId] })
        },
    })

    // Handle assign action - controlled or uncontrolled
    const handleAssign = (widgetId: number) => {
        if (isControlled) {
            onControlledChange([...controlledAssignedIds, widgetId])
            setShowAddWidget(false)
        } else {
            assignMutation.mutate(widgetId)
        }
    }

    // Handle unassign action - controlled or uncontrolled
    const handleUnassign = (widgetId: number) => {
        if (isControlled) {
            onControlledChange(controlledAssignedIds.filter(id => id !== widgetId))
        } else {
            unassignMutation.mutate(widgetId)
        }
    }

    const allWidgets = allWidgetsData?.data?.widgets || []
    
    // In controlled mode, derive assigned widgets from all widgets + controlled IDs
    const assignedWidgets = isControlled
        ? allWidgets.filter((w: CustomWidget) => controlledAssignedIds.includes(w.id))
        : (assignedWidgetsData?.data?.widgets || [])
    const assignedWidgetIds = new Set(assignedWidgets.map((w: CustomWidget) => w.id))

    // Widgets available to add (not already assigned, active, and fully configured)
    const availableWidgets = useMemo(() => {
        return allWidgets.filter((w: CustomWidget) => 
            !assignedWidgetIds.has(w.id) && w.is_active && isWidgetFullyConfigured(w)
        )
    }, [allWidgets, assignedWidgetIds])

    // Group available widgets by type
    const availableByType = useMemo(() => {
        return availableWidgets.reduce((acc: Record<string, CustomWidget[]>, widget: CustomWidget) => {
            if (!acc[widget.type]) acc[widget.type] = []
            acc[widget.type].push(widget)
            return acc
        }, {})
    }, [availableWidgets])

    const isLoading = isLoadingAll || (!isControlled && isLoadingAssigned)

    if (isLoading) {
        return (
            <div className="flex items-center justify-center py-12">
                <Loader2 className="w-8 h-8 animate-spin text-gray-400" />
            </div>
        )
    }

    return (
        <div className="space-y-6">
            {/* Description */}
            <div className="bg-blue-50 border border-blue-200 rounded-lg p-4">
                <p className="text-sm text-blue-800">
                    {t('Assign widgets to this bot. The widgets will be available for use in conversations with customers,')}
                    {' '}{t('and will appear according to the conversation context and AI settings.')}
                </p>
            </div>

            {/* Assigned Widgets */}
            <div>
                <div className="flex items-center justify-between mb-4">
                    <h3 className="text-lg font-medium text-gray-900">
                        {t('Assigned Widgets')} ({assignedWidgets.length})
                    </h3>
                    <div className="flex items-center gap-2">
                        <button
                            onClick={() => setShowAddWidget(true)}
                            disabled={availableWidgets.length === 0}
                            className="flex items-center gap-2 px-3 py-1.5 text-sm bg-primary-600 text-white rounded-lg hover:bg-primary-700 transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
                        >
                            <Plus className="w-4 h-4" />
                            {t('Assign Widget')}
                        </button>
                        <button
                            onClick={() => navigate(`/widgets?returnTo=${encodeURIComponent(`/bots/${botId}?tab=widgets`)}`)}
                            className="px-3 py-1.5 text-sm border border-gray-300 text-gray-700 rounded-lg hover:bg-gray-50 transition-colors"
                        >
                            {t('Create New Widget')}
                        </button>
                    </div>
                </div>

                {assignedWidgets.length === 0 ? (
                    <div className="text-center py-12 bg-gray-50 rounded-lg border-2 border-dashed border-gray-200">
                        <Puzzle className="w-12 h-12 mx-auto text-gray-300 mb-3" />
                        <p className="text-gray-500">{t('No widgets assigned to this bot')}</p>
                        <p className="text-sm text-gray-400 mt-1">
                            {t('Click "Assign Widget" to assign widgets')}
                        </p>
                    </div>
                ) : (
                    <div className="space-y-2">
                        {assignedWidgets.map((widget: CustomWidget) => {
                            const Icon = typeIcons[widget.type] || Puzzle
                            const fields = widget.fields as FormField[] | undefined
                            const widgetIsActive = (() => {
                                const val = widget.is_active
                                if (typeof val === 'boolean') return val
                                if (typeof val === 'number') return val !== 0
                                if (typeof val === 'string') return val !== '0' && val !== ''
                                return false
                            })()
                            const fullyConfigured = isWidgetFullyConfigured(widget)
                            const isDisabled = !widgetIsActive || !fullyConfigured
                            
                            return (
                                <div
                                    key={widget.id}
                                    className={`p-4 bg-white border rounded-lg transition-shadow ${
                                        isDisabled 
                                            ? 'border-gray-200 opacity-50 bg-gray-50' 
                                            : 'border-gray-200 hover:shadow-sm'
                                    }`}
                                >
                                    <div className="flex items-start gap-3">
                                        <div className={`w-10 h-10 rounded-lg flex items-center justify-center flex-shrink-0 ${
                                            isDisabled 
                                                ? 'bg-gray-200 text-gray-400' 
                                                : 'bg-primary-100 text-primary-700'
                                        }`}>
                                            <Icon className="w-5 h-5" />
                                        </div>
                                        <div className="flex-1 min-w-0">
                                            <p className={`font-medium ${isDisabled ? 'text-gray-400' : 'text-gray-900'}`}>
                                                {widget.name}
                                            </p>
                                            <p className="text-sm text-gray-500">
                                                {typeLabels[widget.type] || widget.type}
                                            </p>
                                            
                                            {/* Status badges for disabled widgets */}
                                            {isDisabled && (
                                                <div className="flex flex-wrap gap-1 mt-1">
                                                    {!widgetIsActive && (
                                                        <span className="text-xs px-2 py-0.5 bg-gray-200 text-gray-500 rounded">
                                                            {t('Disabled')}
                                                        </span>
                                                    )}
                                                    {!fullyConfigured && (
                                                        <span className="text-xs px-2 py-0.5 bg-amber-100 text-amber-700 rounded">
                                                            {t(WIDGET_CONFIG_HINTS[widget.type] || 'Not fully configured')}
                                                        </span>
                                                    )}
                                                </div>
                                            )}
                                            
                                            {/* Widget description (when to use) */}
                                            {!isDisabled && widget.description && (
                                                <p className="text-xs text-gray-400 mt-1 line-clamp-2">
                                                    {widget.description}
                                                </p>
                                            )}
                                            
                                            {/* Form fields preview */}
                                            {widget.type === 'form' && fields && fields.length > 0 && (
                                                <div className="mt-2 flex flex-wrap gap-1">
                                                    {fields.map((field: FormField, idx: number) => (
                                                        <span 
                                                            key={idx}
                                                            className="text-xs px-2 py-0.5 bg-gray-100 text-gray-600 rounded"
                                                        >
                                                            {field.label}
                                                        </span>
                                                    ))}
                                                </div>
                                            )}
                                        </div>
                                        
                                        {/* Action buttons */}
                                        <div className="flex gap-1 flex-shrink-0">
                                            {/* Edit button */}
                                            <button
                                                onClick={() => navigate(`/widgets/${widget.id}?returnTo=${encodeURIComponent(`/bots/${botId}?tab=widgets`)}`)}
                                                className="p-2 text-gray-400 hover:text-primary-600 hover:bg-primary-50 rounded-lg transition-colors"
                                                title={t('Edit Widget')}
                                            >
                                                <Pencil className="w-4 h-4" />
                                            </button>
                                            
                                            {/* Remove button */}
                                            <button
                                                onClick={() => handleUnassign(widget.id)}
                                                className="p-2 text-gray-400 hover:text-red-600 hover:bg-red-50 rounded-lg transition-colors"
                                                title={t('Remove from Bot')}
                                            >
                                                <Trash2 className="w-4 h-4" />
                                            </button>
                                        </div>
                                    </div>
                                </div>
                            )
                        })}
                    </div>
                )}
            </div>

            {/* Add Widget Modal */}
            {showAddWidget && (
                <div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50">
                    <div className="bg-white rounded-xl shadow-xl max-w-lg w-full mx-4 max-h-[80vh] flex flex-col">
                        <div className="flex items-center justify-between px-6 py-4 border-b">
                            <h3 className="text-lg font-semibold">{t('Assign Widget')}</h3>
                            <button
                                onClick={() => setShowAddWidget(false)}
                                className="p-1 text-gray-400 hover:text-gray-600 rounded"
                            >
                                <X className="w-5 h-5" />
                            </button>
                        </div>
                        
                        <div className="flex-1 overflow-y-auto p-6">
                            {availableWidgets.length === 0 ? (
                                <div className="text-center py-8 text-gray-500">
                                    <p>{t('No widgets available for assignment')}</p>
                                    <p className="text-sm mt-1">
                                        {t('Create new widgets on the Widgets page')}
                                    </p>
                                </div>
                            ) : (
                                <div className="space-y-6">
                                    {Object.entries(availableByType).map(([type, widgets]) => {
                                        const Icon = typeIcons[type] || Puzzle
                                        return (
                                            <div key={type}>
                                                <h4 className="text-sm font-medium text-gray-500 mb-2 flex items-center gap-2">
                                                    <Icon className="w-4 h-4" />
                                                    {typeLabels[type] || type}
                                                </h4>
                                                <div className="space-y-2">
                                                    {widgets.map((widget: CustomWidget) => (
                                                        <button
                                                            key={widget.id}
                                                            onClick={() => handleAssign(widget.id)}
                                                            disabled={!isControlled && assignMutation.isPending}
                                                            className="w-full flex items-center justify-between p-3 bg-gray-50 hover:bg-primary-50 border border-gray-200 hover:border-primary-300 rounded-lg transition-colors disabled:opacity-50"
                                                        >
                                                            <span className="font-medium text-gray-700">
                                                                {widget.name}
                                                            </span>
                                                            {!isControlled && assignMutation.isPending && assignMutation.variables === widget.id ? (
                                                                <Loader2 className="w-5 h-5 animate-spin text-primary-600" />
                                                            ) : (
                                                                <Plus className="w-5 h-5 text-gray-400" />
                                                            )}
                                                        </button>
                                                    ))}
                                                </div>
                                            </div>
                                        )
                                    })}
                                </div>
                            )}
                        </div>
                        <div className="px-6 py-4 border-t">
                            <button
                                onClick={() => navigate(`/widgets?returnTo=${encodeURIComponent(`/bots/${botId}?tab=widgets`)}`)}
                                className="w-full px-4 py-2 border border-gray-300 text-gray-700 rounded-lg hover:bg-gray-50 transition-colors"
                            >
                                {t('Create New')}
                            </button>
                        </div>
                    </div>
                </div>
            )}
        </div>
    )
}

export default WidgetAssignment

