import { useRef, useState, useEffect, } from 'react';

import { Button, TabPanel, SelectControl,ProgressBar, Popover, Modal, Dropdown, Panel, PanelBody, PanelRow, Spinner, 
    __experimentalDivider as Divider,
    __experimentalToggleGroupControl as ToggleGroupControl,
    __experimentalToggleGroupControlOption as ToggleGroupControlOption,    
    //@ts-ignore
} from '@wordpress/components';
import { image, video, gallery, close, chevronUp } from '@wordpress/icons';



import { useToolsContext } from './ContextProvider';
import { TOOL_REGISTRY } from './constants'
import type { IoNames, ToolIds } from './types';

import ToolImg2Img from './tools/img2img/ToolImg2Img';
import ToolImg2Vid from './tools/img2vid/ToolImg2Vid';
import ToolVid2Ssq from './tools/vid2ssq/ToolVid2Ssq';

import { actionGenerate } from './actionGenerate';

import OutputsDisplay from './OutputsDisplay';
import NoticeTracking from '../../../../../shared/NoticeTracking';
import NoticeCredits from '../../../../../shared/NoticeCredits';

export default function MediaTools({ attributes, setAttributes, setShow }: { attributes:any, setAttributes:any, setShow: React.Dispatch<React.SetStateAction<'canvas' | 'adder' | 'media-tools'>> }) {
    const { activeToolId, activeIo } = useToolsContext();
    const [ elementSize, setElementSize  ] = useState<'s' | 'm' | 'l' | null>(null);
    const rootRef = useRef<HTMLDivElement>(null);
   
    useEffect(() => {
        const sizeThresholds = [
            { size: 's', width: 400 },
            { size: 'm', width: 650 },
            { size: 'l', width: 800 },
        ] as const;

        function getSizeCategory(width: number): 's' | 'm' | 'l' {
            const found = [...sizeThresholds].reverse().find(threshold => width >= threshold.width);
            return found ? found.size : sizeThresholds[0].size;
        }

        const handleResize = (width: number) => {
            setElementSize(getSizeCategory(width));
        };

        const observer = new window.ResizeObserver(entries => {
            for (let entry of entries) {
                if (entry.target === rootRef.current && entry.contentRect) {
                    handleResize(entry.contentRect.width);
                }
            }
        });

        if (rootRef.current) {
            observer.observe(rootRef.current);
            // Set initial size
            handleResize(rootRef.current.offsetWidth);
        }

        return () => {
            observer.disconnect();
        };
    }, []);

    if (elementSize === null) {
        return <div ref={rootRef} style={{ width: '100%', minHeight: "450px", display: "flex", alignItems: "center", justifyContent: "center" }}>Loading...</div>;
    }

    return (
        <div ref={rootRef} id="ssq-c2d-tools-width-ref" style={{ display: "flex", flexDirection: "column", alignItems: "stretch", minHeight: "450px", width: "100%"}}>
            <div 
                style={{ 
                    display: "flex", 
                    justifyContent: "space-between", 
                    alignItems: "center", 
                    marginBottom: "12px", 
                    width: "calc(100% - 16px)" 
                }}
            >
                <ToolSelectControl elementSize={elementSize} /> 
                { (elementSize === 's' || elementSize === 'm') && <IoSelectControl elementSize={elementSize} /> }
            </div>
            <div id="ssq-c2d-tools-content" style={{ flexGrow: 1 }}>
                { (elementSize === 's' || elementSize === 'm') 
                    ?
                        <div style={{ maxWidth: "500px"}}>
                            {
                                activeIo === 'input' && (
                                    activeToolId === 'img2img' ? <ToolImg2Img /> :
                                    activeToolId === 'img2vid' ? <ToolImg2Vid /> :
                                    activeToolId === 'vid2ssq' ? <ToolVid2Ssq /> :
                                    <div>Unknown tool selected</div>
                                )
                            }
                            {
                                activeIo === 'output' && 
                                    <>
                                        <OutputsDisplay elementSize={elementSize} attributes={attributes} setAttributes={setAttributes} setShow={setShow} />
                                    </>
                            }
                        </div>                    
                    : // large size layout
                    <div style={{ display: "flex", justifyContent: "space-between", gap: 12 }} >
                        <div style={{ flexGrow: 1, maxWidth: "50%" }} >
                            {(        
                                activeToolId === 'img2img' ? <ToolImg2Img /> :
                                activeToolId === 'img2vid' ? <ToolImg2Vid /> :
                                activeToolId === 'vid2ssq' ? <ToolVid2Ssq /> :
                                <div>Unknown tool selected</div>      
                            )}                      
                        </div>
                        <Divider
                            margin="2"
                            orientation="vertical"
                        />                        
                        <div style={{ flexGrow: 1,  maxWidth: "50%" }} >
                            <OutputsDisplay elementSize={elementSize} attributes={attributes} setAttributes={setAttributes} setShow={setShow} />
                        </div>
                    </div>
                }
            </div>
            <div style={{ marginTop: "12px" }}>
                <NoticeTracking />
                <NoticeCredits />
            </div>
            <div id="ssq-c2d-tools-progress">
                <ProgressDisplay />
            </div>            
        </div>
    )
}

function ToolSelectControl({elementSize}: {elementSize: 's' | 'm' | 'l'}) {
    const { activeToolId, setActiveToolId, activeIo } = useToolsContext();
    const availableTools = TOOL_REGISTRY.map((tool) => ({ label: tool.title, value: tool.id }));

    return (
        <div 
            style={{ visibility: (activeIo === 'output' && (elementSize === 's' || elementSize === 'm') ) ? "hidden" : "visible" }} // hide when output is active
        >
            <SelectControl
                //label="Size"
                value={activeToolId}
                options={availableTools}
                onChange={ ( newToolId : ToolIds ) => setActiveToolId( newToolId ) }
                __next40pxDefaultSize
                __nextHasNoMarginBottom
            />
        </div>
    );
};

function IoSelectControl({elementSize}:{elementSize: 's' | 'm' | 'l'}) {
    const { activeIo, setActiveIo, outputs } = useToolsContext();

    return (
        <ToggleGroupControl
            label={'Input/Output toggle'}
            hideLabelFromVision={true}
            value={activeIo}
            onChange={(value: IoNames) => setActiveIo(value)}   
            isBlock
            __nextHasNoMarginBottom
            __next40pxDefaultSize
        >
            <ToggleGroupControlOption value="input" label={elementSize === 's' ? 'In' : 'Input'} />
            <ToggleGroupControlOption value="output" label={elementSize === 's' ? 'Out' : 'Output'} />
        </ToggleGroupControl>        
    )    
}

// function OutputsDisplay() {
//     const { outputs, outputActiveIndex } = useToolsContext();
//     return (
//         <div>
//             Outputs:
//             { outputs.map((output, index) => {
//                 switch (output.fileType) {
//                     case 'image':
//                         return (
//                             <div key={index}>
//                                 🖼️ Image: {output.url} - {output.timestamp}
//                             </div>
//                         );
//                     case 'video':
//                         return (
//                             <div key={index}>
//                                 🎬 Video: {output.url} - {output.timestamp}
//                             </div>
//                         );
//                     case 'ssq':
//                         return (
//                             <div key={index}>
//                                 🗂️ SSQ: {output.imageIds?.join(', ')} - {output.timestamp}
//                             </div>
//                         );
//                     default:
//                         return null;
//                 }
//             })}
//         </div>
//     )
// }

function ProgressDisplay() {
    const toolsState = useToolsContext();

    return (
        <>
            <div style={{ marginTop: "12px", fontSize: "12px", color: "#666", display: "flex", flexDirection: "row", alignItems: "center", justifyContent: "space-between", gap: "6px" }}>
                <div style={{ display: "flex", justifyContent: "center", alignItems: "center"}}>
                    <Dropdown
                        popoverProps={ { placement: 'top-start' } }
                        renderToggle={ ( { isOpen, onToggle }: { isOpen: boolean; onToggle: () => void } ) => (
                            <Button
                                variant="tertiary"
                                icon={ (toolsState.progress.log.length === 0) ? chevronUp : undefined }
                                //size="small"
                                onClick={ onToggle }
                                aria-expanded={ isOpen }
                            >
                                {toolsState.progress.log.length === 0
                                    ? (
                                        <span>
                                            Logs
                                        </span>
                                    ) : (
                                            <span style={{color: getLogColor(toolsState.progress.log[toolsState.progress.log.length - 1].level), fontWeight: "bold", marginRight: "6px"}}>
                                                {`${toolsState.progress.log[toolsState.progress.log.length - 1].level.toUpperCase()}`}                                        
                                            </span>
                                    )
                                }
                            </Button>
                        ) }
                        renderContent={()=>(<LogsDisplay/>)}
                    />
                    <span style={{ marginLeft: "12px" }}>
                        { !(toolsState.progress.log.length === 0) && (
                            <span>{truncateString(toolsState.progress.log[toolsState.progress.log.length - 1].message, 80)}</span>
                        )}
                    </span>
                </div>


            </div>

        </>
    )
}



function LogsDisplay(){
    const toolsState = useToolsContext();
    const { activeToolId } = toolsState;

    // display
    const [ display, setDisplay ] = useState<'logs' | 'state'>('logs');
    // app state
    const [ filterDebug, setFilterDebug ] = useState<'all' | 'curTool' | 'progress' | 'output'>('all');
    const curToolState = toolsState.tools.find(tool => tool.id === activeToolId);



    return (
        <>
            <ToggleGroupControl
                label="Display"
                isBlock
                __nextHasNoMarginBottom
                __next40pxDefaultSize
                value={display}
                onChange={(value: 'logs' | 'state') => setDisplay(value)}
                style={{  width: "400px", marginBottom: "8px" }}
            >
                <ToggleGroupControlOption value="logs" label="Logs" />
                <ToggleGroupControlOption value="state" label="App State" />
            </ToggleGroupControl>

            <div style={{ minWidth: "520px"}}>
                <div style={{ marginBottom: "12px" }}>
                    { display === 'logs' &&
                        <>
                            <strong>Logs:</strong>
                            <div style={{ maxHeight: "180px", overflowY: "auto", fontSize: "12px", background: "#fafafa", border: "1px solid #eee", borderRadius: "4px", padding: "8px" }}>
                                {toolsState.progress.log.length === 0 ? (
                                    <div>No logs yet.</div>
                                ) : (
                                    toolsState.progress.log.slice().reverse().map((entry, idx) => (
                                        <div key={idx} style={{ marginBottom: "6px", display: "flex", flexDirection: "row", justifyContent: "space-between" }}>
                                            <div>
                                                <span style={{ color: "#888" }}>{new Date(entry.timestamp).toLocaleTimeString()}</span>
                                                <span style={{ marginLeft: "8px", fontWeight: (idx === 0 ? "bold" : undefined) }}>{entry.message}</span>
                                            </div>
                                            <span 
                                                style={{ 
                                                    marginLeft: "8px", 
                                                    fontWeight: (idx === 0 ? "bold" : undefined), 
                                                    color: getLogColor(entry.level) }}
                                            >
                                                {entry.level.toUpperCase()}
                                            </span>
                                        </div>
                                    ))
                                )}
                            </div>
                        </>
                    }    
                    { display === 'state' &&
                        <>
                            <ToggleGroupControl
                                label="Debug Filter"
                                isBlock
                                __nextHasNoMarginBottom
                                __next40pxDefaultSize
                                value={filterDebug}
                                onChange={(value: 'all' | 'curTool' | 'progress' | 'output') => setFilterDebug(value)}
                                style={{  width: "400px", marginBottom: "8px" }}
                            >
                                <ToggleGroupControlOption value="all" label="All" />
                                <ToggleGroupControlOption value="curTool" label="Cur Tool" />
                                <ToggleGroupControlOption value="progress" label="Progress" />
                                <ToggleGroupControlOption value="output" label="Outputs" />
                            </ToggleGroupControl>
                            <div style={{ maxHeight: "400px", overflowY: "auto", fontSize: "12px", background: "#fafafa", border: "1px solid #eee", borderRadius: "4px", padding: "8px" }}>
                                { filterDebug === 'all' && <pre>{ JSON.stringify(toolsState, null, 2) }</pre> }
                                { filterDebug === 'curTool' && <pre>{ JSON.stringify(curToolState, null, 2) }</pre> }
                                { filterDebug === 'progress' && <pre>{ JSON.stringify(toolsState.progress, null, 2) }</pre> }
                                { filterDebug === 'output' && <pre>{ JSON.stringify(toolsState.outputs, null, 2) }</pre> }
                            </div>
                        </>
                    }
                </div>
            </div>
        </>
    )
}


// helpers 
function getLogColor(level: string) {
    switch (level) {
        case 'error': return '#d00';
        case 'warning': return '#e6a700';
        case 'success': return '#008a20';
        default: return '#444';
    }
}

function truncateString(s: string, len = 8) {
    if (!s) return '';
    return s.length > len ? s.slice(0, len) + '…' : s;
}