'use client'
import React, {ReactNode, useContext, useState} from 'react';
import {ArrowDown, ArrowUp} from 'lucide-react';
import {useTranslations} from '@/lib/i18n';
import {SessionContext, SessionContextProps} from '@/context/SessionContext';
import {AlertContext, AlertContextProps} from '@/context/AlertContext';
import {LangContext, LangContextProps} from '@/context/LangContext';
import {apiPost} from '@/lib/api/client';
import IconButton from '@/components/ui/IconButton';

export type SyncElementType = 'character' | 'world' | 'location' | 'spell';

interface SyncFieldWrapperProps {
    children: ReactNode;
    seriesElementId: string | null | undefined;
    seriesValue: string;
    currentValue: string;
    bookElementId: string;
    field: string;
    elementType: SyncElementType;
    onDownload: () => void;
    onSyncComplete?: () => void;
}

interface SeriesSyncUploadResponse {
    success: boolean;
    updatedCount: number;
}

export default function SyncFieldWrapper({
                                             children,
                                             seriesElementId,
                                             seriesValue,
                                             currentValue,
                                             bookElementId,
                                             field,
                                             elementType,
                                             onDownload,
                                             onSyncComplete
                                         }: SyncFieldWrapperProps) {
    const t = useTranslations();
    const {session}: SessionContextProps = useContext<SessionContextProps>(SessionContext);
    const {errorMessage, successMessage}: AlertContextProps = useContext<AlertContextProps>(AlertContext);
    const {lang}: LangContextProps = useContext<LangContextProps>(LangContext);
    
    const [isUploading, setIsUploading] = useState<boolean>(false);
    
    const isLinkedToSeries: boolean = !!seriesElementId;
    const hasSeriesDiff: boolean = isLinkedToSeries && seriesValue !== currentValue;
    
    async function handleUpload(): Promise<void> {
        if (!seriesElementId || isUploading) return;
        
        setIsUploading(true);
        try {
            const response: SeriesSyncUploadResponse = await apiPost<SeriesSyncUploadResponse>(
                'series/propagate',
                {
                    type: elementType,
                    bookElementId: bookElementId,
                    field: field,
                    value: currentValue
                },
                session.accessToken,
                lang
            );
            if (response.success) {
                successMessage(t('syncField.uploadSuccess', {count: response.updatedCount}));
                if (onSyncComplete) {
                    onSyncComplete();
                }
            }
        } catch (e: unknown) {
            if (e instanceof Error) {
                errorMessage(e.message);
            }
        } finally {
            setIsUploading(false);
        }
    }
    
    function handleDownload(): void {
        onDownload();
    }
    
    if (!isLinkedToSeries) {
        return <>{children}</>;
    }
    
    return (
        <div className="flex items-center gap-2 w-full">
            <IconButton
                icon={ArrowDown}
                variant={hasSeriesDiff ? 'primary' : 'muted'}
                size="sm"
                onClick={handleDownload}
                disabled={!hasSeriesDiff}
                tooltip={t('syncField.downloadTooltip')}
            />

            <div className="flex-grow">
                {children}
            </div>
            
            <IconButton
                icon={ArrowUp}
                variant={hasSeriesDiff && !isUploading ? 'primary' : 'muted'}
                size="sm"
                onClick={handleUpload}
                disabled={isUploading || !hasSeriesDiff}
                tooltip={t('syncField.uploadTooltip')}
            />
        </div>
    );
}
