//@ts-ignore
import { __ } from '@wordpress/i18n';

//@ts-ignore
import { Button, Icon, FormFileUpload, Dropdown, TextControl } from '@wordpress/components';
import { upload, cancelCircleFilled, wordpress } from '@wordpress/icons';
import WpMediaUploader from '../../../../../../shared/media-2d/components/WpMediaUploader'
import type { ToolsContextType, UpdateProgressParams } from '../types';
import fsPublicDataManager from '../../../../../../shared/fsPublicDataManager';

declare const scroll_sequence_editor_data: any;

/*

IMPORTANT: 

1) When using set{State} with objects, always use the functional form to avoid stale closures, e.g.
    setModelStateFx( ( prev : ModelStateFx ) => ( {
        ...prev,
        input: {
            ...prev.input,
            image_url: s3Url
        }
    }));
2) try not to use  useToolsContext(); here, instead pass it down from parent. It should be safe in combination with (1) above.


*/

export default function InputImagesControl({
    label,
    progress,

    imageS3Url,

    onUploadFinished, // handles the relevant s3Url+filename to be added to states
    onRemove, // handles removing the relevant s3Url+filename from states

}:{
    label: string;
    progress: ToolsContextType['progress']

    imageS3Url: string // current image s3Url for this slot

    onUploadFinished: (s3Url: string, fileName: string) => void;
    onRemove: () => void;

}) {
    const { busy, updateProgress} = progress // does not use Context progress directly, as this is a shared folder

    // Handle WP Media selection
    async function handleWpSelection(attachments: any[]) {
        if (!attachments.length) return;

        updateProgress({ 
            busy: 'uploading', 
            log: {
                level: 'info', 
                message: `Started WP Media upload for ${label}`, 
                data: { label: label,  filename: attachments[0].filename,  }
            }
        } );

        try {
            // Only first image for this slot
            const att = attachments[0];
            // Convert to File
            const fileName = att.filename ? att.filename : `wp-${att.id}.png`; 
            const file = await urlToFile(att.url, fileName);
            // if (await isDuplicate(file)) {
            //     onLoadingChange(slotKey, false);
            //     return;
            // }
            const s3Url = await uploadFileToS3(file);

            // SUCCESS 
            onUploadFinished(s3Url, fileName);

            updateProgress({ 
                busy: false, 
                log: {
                    level: 'success',
                    message: `WP Media upload complete for ${label}`,
                    data: { label: label, filename: fileName, s3Url: s3Url }
                }
            } );

        } catch (e) {
            const niceError = e instanceof Error ? e.message : String(e);
            updateProgress({ 
                busy: false, 
                log: {
                    level: 'error',
                    message: `Error: ${niceError} Could not add ${label} from WordPress Media.`,
                    data: {
                        error: e,
                        label:label, 
                        filename: attachments[0].filename,
                        filesizeHumanReadable: attachments[0].filesizeHumanReadable,
                        id: attachments[0].id,
                        url: attachments[0].url,
                        type: attachments[0].type
                    }
                }
            } );
        }
    }

    // Handle device upload
    async function handleDeviceUpload(event: React.ChangeEvent<HTMLInputElement>) {
        // should i reset the error to null here? 
        const files = Array.from(event.currentTarget.files || []);
        if (!files.length) return;
        const file = files[0];
        const fileName = file.name ? file.name : `device-${Date.now()}.png`;

        updateProgress({ 
            busy: 'uploading', 
            log: {
                level: 'info',
                message: `Started device upload for ${label}`,
                data: { label: label, filename: fileName }
            }
        });

        try {
            //setPercent(10);
            const s3Url = await uploadFileToS3(file);
            //setPercent(100);

            // SUCCESS 
            onUploadFinished(s3Url, fileName);

            updateProgress({ 
                busy: false, 
                log: {
                    level: 'success',
                    message: `Device upload complete for ${label}`,
                    data: { label: label, filename: fileName, s3Url: s3Url, }
                }
            } );

        } catch (e) {
            const niceError = e instanceof Error ? e.message : String(e);
            updateProgress({ 
                busy: false, 
                log: {
                    level: 'error',
                    message: `Error: ${niceError}. Could not add ${label} from your device.`,
                    data: { error: e, label: label, filename: fileName, filesize: file.size, filetype: file.type }
                }
            } );

        }
    }
    // Remove image from slot
    function handleRemove(imageS3Url: string) {
        updateProgress({
            busy: false,
            log: {
                level: 'info',
                message: `Removed Image "${imageS3Url}" `,
                data: { imageS3Url }
            }
        });
        onRemove()
    }

    return (
        <div style={{ display: 'flex', gap: 16, marginBottom: 8, marginTop: 32 }}>
            <div style={{ position: 'relative', width: 160, height: 160 }}>
                <div 
                    style={{ 
                        position: 'absolute', 
                        top: "-24px", 
                        left: 0, 
                        fontSize: 11, 
                        fontWeight: 500, 
                        lineHeight: 1.4, 
                        textTransform: 'uppercase',
                    }}
                >
                    {label}
                </div>
                {imageS3Url ? (
                    <>
                        <img src={imageS3Url} alt="" style={{ width: 160, height: 160, objectFit: 'cover', borderRadius: 6, boxShadow: '0 1px 4px rgba(0,0,0,0.08)' }} />
                        <Button
                            icon={<Icon icon={cancelCircleFilled} />}
                            label="Remove image"
                            isSmall
                            isDestructive
                            style={{ position: 'absolute', top: "-12px", right: "-12px", background: 'rgb(255,255,255)', borderRadius: '50%', padding: 0, minWidth: 28, minHeight: 28 }}
                            onClick={() => handleRemove(imageS3Url)}
                        />
                        { busy === 'uploading' && <div style={{ position: 'absolute', left: 0, top: 0, width: '100%', height: '100%', background: 'rgba(255,255,255,0.7)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>Uploading...</div>}
                    </>
                ) : (
                    <>
                        <Dropdown
                            position="bottom left"
                            //isOpen={activeSlot === slot.key}
                            //onToggle={() => setActiveSlot(activeSlot === slot.key ? null : slot.key)}                            
                            renderToggle={({ isOpen, onToggle }: { isOpen: boolean; onToggle: () => void }) => (
                                <Button
                                    icon={<Icon icon={upload}/>}
                                    variant="secondary"
                                    style={{ width: 160, height: 160, borderRadius: 6, display: 'flex', alignItems: 'center', justifyContent: 'center' }}
                                    aria-expanded={isOpen}
                                    onClick={() => {
                                        onToggle();
                                    }}
                                />
                            )}
                            renderContent={({ onClose }: { onClose: () => void }) => (
                                <div style={{ background: 'white', border: '1px solid #eee', borderRadius: 6, padding: 8, minWidth: 180 }}>
                                    <div>
                                        <WpMediaUploader
                                            fileType='image'
                                            multiple={false}
                                            returnType='full'
                                            onCompleteSelection={(attachments: any[]) => {
                                                onClose();
                                                handleWpSelection(attachments);
                                            }}
                                        >
                                            {(runUploader) => (
                                                <Button icon={<Icon icon={wordpress} />} onClick={runUploader} variant="tertiary">WP Media</Button>
                                            )}
                                        </WpMediaUploader>
                                    </div>
                                    <div>
                                        <FormFileUpload
                                            accept="image/*"
                                            multiple={false}
                                            onChange={(e: any) => { 
                                                onClose(); 
                                                handleDeviceUpload(e); 
                                            }}
                                            render={({ openFileDialog }:any) => (
                                                <Button variant="tertiary" onClick={openFileDialog} icon={<Icon icon={upload} />}>Device</Button>
                                            )}
                                        />
                                    </div>
                                    <div>
                                        <Button variant="tertiary" disabled>Recent Outputs (coming soon)</Button>
                                    </div>
                                    <div>
                                        <Button variant="tertiary" disabled>History (coming soon)</Button>
                                    </div>
                                    {/* 
                                    // DISABLED FOR NOW - URL UPLOAD IS TRICKY UX-WISE
                                    <div>
                                        <input
                                            // This sort of works better than TextControl for onBlur
                                            type="text"
                                            placeholder="Paste image URL"
                                            style={{ width: '100%', marginTop: 4 }}
                                            onBlur={e => { setActiveSlot(null); onClose(); handleUrlInput(slot.key, e.target.value); }}
                                        /> 
                                        <TextControl
                                            __nextHasNoMarginBottom
                                            __next40pxDefaultSize
                                            type="url"
                                            label="Image URL (coming soon)"
                                            placeholder="Paste image URL"
                                            disabled={true} // Temporarily disabled
                                            // onBlur={(e: React.FocusEvent<HTMLInputElement>) => { 
                                            //     console.log('TextControl onBlur URL:', e.target.value);
                                            //     setActiveSlot(null); 
                                            //     onClose(); 
                                            //     handleUrlInput(slot.key, e.target.value); 
                                            // }}
                                            onChange={ ( value:any ) => console.log('onChange URL value:', value ) } // Should really be onblur as above.
                                        />                                                
                                    </div>
                                    <Button variant="link" onClick={() => { setActiveSlot(null); onClose(); }} style={{ marginTop: 8 }}>Cancel</Button> 
                                    */}
                                </div>
                            )}

                        />
                        { busy === 'uploading' && <div style={{ position: 'absolute', inset: 5, background: 'rgba(255,255,255,1)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>Uploading...</div>}
                    </>
                )}
            </div>            
        </div>
    )
}



// Helper: Upload a File to S3 using presigned POST data from your backend
async function uploadFileToS3(file: File): Promise<string> {

    const response = await fetch(`${scroll_sequence_editor_data.scrollSequenceApiUrl}/v2/media-tools/upload`, {
        method: 'POST',
        headers: {
            'Authorization': `${scroll_sequence_editor_data.fs_auth_hash}`,
            'Content-Type': 'application/json',
        },
        body: JSON.stringify({ filename: file.name, contentType: file.type }),
    });

    const { url, fields, fsPublicData, success, error } = await response.json();

    if (!success){
        throw new Error( error || 'Failed to get presigned URL' );
    } // check for successful response

    if (fsPublicData) {
        //console.log(' uploadFileToS3() - updating fsPublicDataManager with new fsPublicData:', fsPublicData);
        fsPublicDataManager.update(fsPublicData);
    }

    console.log('S3 upload URL:', url);

    const formData = new FormData();
    Object.entries(fields).forEach(([key, value]) => {
        formData.append(key, value as string);
    });
    formData.append('file', file);

    const uploadResponse = await fetch(url, { method: 'POST', body: formData });
    if (!uploadResponse.ok) throw new Error('S3 upload failed');

    return `${url}${fields.key}`;
}

// Helper: Convert a remote image URL to a File object
async function urlToFile(url: string, filename: string): Promise<File> {
    const res = await fetch(url);
    const blob = await res.blob();
    const type = blob.type || 'image/png';
    return new File([blob], filename, { type });
}
// Helper: Slugify a filename (remove spaces, special chars, lowercase)
function slugifyFilename(name: string) {
    return name
        .toLowerCase()
        .replace(/\s+/g, '-')
        .replace(/[^a-z0-9\-.]/g, '');
}