import React, {useState} from 'react';

import {
    CornerDownLeft,
    Hammer, Pin, Menu
} from "lucide-react"

import {
    Button
} from "@/components/ui/button.tsx"

import {
    Sidebar,
    SidebarContent,
    SidebarGroup,
    SidebarGroupContent,
    SidebarGroupLabel,
    SidebarMenu,
    SidebarMenuItem, SidebarProvider,
} from "@/components/ui/sidebar.tsx"

import {
    Separator,
} from "@/components/ui/separator.tsx"
import {
    Sheet,
    SheetContent,
    SheetHeader,
    SheetTitle,
    SheetTrigger
} from "@/components/ui/sheet.tsx";
import {
    Accordion,
    AccordionContent,
    AccordionItem,
    AccordionTrigger,
} from "@/components/ui/accordion.tsx";
import {ScrollArea} from "@/components/ui/scroll-area.tsx";
import {Input} from "@/components/ui/input.tsx";
import {getSSHHosts} from "@/apps/SSH/ssh-axios";
import {Checkbox} from "@/components/ui/checkbox.tsx";

interface SSHHost {
    id: number;
    name: string;
    ip: string;
    port: number;
    username: string;
    folder: string;
    tags: string[];
    pin: boolean;
    authType: string;
    password?: string;
    key?: string;
    keyPassword?: string;
    keyType?: string;
    enableTerminal: boolean;
    enableTunnel: boolean;
    enableConfigEditor: boolean;
    defaultPath: string;
    tunnelConnections: any[];
    createdAt: string;
    updatedAt: string;
}

export interface SidebarProps {
    onSelectView: (view: string) => void;
    onHostConnect: (hostConfig: any) => void;
    allTabs: { id: number; title: string; terminalRef: React.RefObject<any> }[];
    runCommandOnTabs: (tabIds: number[], command: string) => void;
    onCloseSidebar?: () => void;
    onAddHostSubmit?: (data: any) => void;
    open?: boolean;
    onOpenChange?: (open: boolean) => void;
}

export function SSHSidebar({
                               onSelectView,
                               onHostConnect,
                               allTabs,
                               runCommandOnTabs,
                               onCloseSidebar,
                               open,
                               onOpenChange
                           }: SidebarProps): React.ReactElement {
    const [hosts, setHosts] = useState<SSHHost[]>([]);
    const [hostsLoading, setHostsLoading] = useState(false);
    const [hostsError, setHostsError] = useState<string | null>(null);
    const prevHostsRef = React.useRef<SSHHost[]>([]);

    const fetchHosts = React.useCallback(async () => {
        setHostsLoading(true);
        setHostsError(null);
        try {
            const newHosts = await getSSHHosts();
            const terminalHosts = newHosts.filter(host => host.enableTerminal);

            const prevHosts = prevHostsRef.current;
            const isSame =
                terminalHosts.length === prevHosts.length &&
                terminalHosts.every((h: SSHHost, i: number) => {
                    const prev = prevHosts[i];
                    if (!prev) return false;
                    return (
                        h.id === prev.id &&
                        h.name === prev.name &&
                        h.folder === prev.folder &&
                        h.ip === prev.ip &&
                        h.port === prev.port &&
                        h.username === prev.username &&
                        h.password === prev.password &&
                        h.authType === prev.authType &&
                        h.key === prev.key &&
                        h.pin === prev.pin &&
                        JSON.stringify(h.tags) === JSON.stringify(prev.tags)
                    );
                });
            if (!isSame) {
                setHosts(terminalHosts);
                prevHostsRef.current = terminalHosts;
            }
        } catch (err: any) {
            setHostsError('Failed to load hosts');
        } finally {
            setHostsLoading(false);
        }
    }, []);

    React.useEffect(() => {
        fetchHosts();
        const interval = setInterval(fetchHosts, 10000);
        return () => clearInterval(interval);
    }, [fetchHosts]);

    const [search, setSearch] = useState("");
    const [debouncedSearch, setDebouncedSearch] = useState("");
    React.useEffect(() => {
        const handler = setTimeout(() => setDebouncedSearch(search), 200);
        return () => clearTimeout(handler);
    }, [search]);

    const filteredHosts = React.useMemo(() => {
        if (!debouncedSearch.trim()) return hosts;
        const q = debouncedSearch.trim().toLowerCase();
        return hosts.filter(h => {
            const searchableText = [
                h.name || '',
                h.username,
                h.ip,
                h.folder || '',
                ...(h.tags || []),
                h.authType,
                h.defaultPath || ''
            ].join(' ').toLowerCase();
            return searchableText.includes(q);
        });
    }, [hosts, debouncedSearch]);

    const hostsByFolder = React.useMemo(() => {
        const map: Record<string, SSHHost[]> = {};
        filteredHosts.forEach(h => {
            const folder = h.folder && h.folder.trim() ? h.folder : 'No Folder';
            if (!map[folder]) map[folder] = [];
            map[folder].push(h);
        });
        return map;
    }, [filteredHosts]);

    const sortedFolders = React.useMemo(() => {
        const folders = Object.keys(hostsByFolder);
        folders.sort((a, b) => {
            if (a === 'No Folder') return -1;
            if (b === 'No Folder') return 1;
            return a.localeCompare(b);
        });
        return folders;
    }, [hostsByFolder]);

    const getSortedHosts = (arr: SSHHost[]) => {
        const pinned = arr.filter(h => h.pin).sort((a, b) => (a.name || '').localeCompare(b.name || ''));
        const rest = arr.filter(h => !h.pin).sort((a, b) => (a.name || '').localeCompare(b.name || ''));
        return [...pinned, ...rest];
    };

    const [toolsSheetOpen, setToolsSheetOpen] = useState(false);
    const [toolsCommand, setToolsCommand] = useState("");
    const [selectedTabIds, setSelectedTabIds] = useState<number[]>([]);

    const handleTabToggle = (tabId: number) => {
        setSelectedTabIds(prev => prev.includes(tabId) ? prev.filter(id => id !== tabId) : [...prev, tabId]);
    };

    const handleRunCommand = () => {
        if (selectedTabIds.length && toolsCommand.trim()) {
            let cmd = toolsCommand;
            if (!cmd.endsWith("\n")) cmd += "\n";
            runCommandOnTabs(selectedTabIds, cmd);
            setToolsCommand("");
        }
    };

    function getCookie(name: string) {
        return document.cookie.split('; ').reduce((r, v) => {
            const parts = v.split('=');
            return parts[0] === name ? decodeURIComponent(parts[1]) : r;
        }, "");
    }

    const updateRightClickCopyPaste = (checked) => {
        document.cookie = `rightClickCopyPaste=${checked}; expires=2147483647; path=/`;
    }

    return (
        <SidebarProvider open={open} onOpenChange={onOpenChange}>
            <Sidebar className="h-full flex flex-col overflow-hidden">
                <SidebarContent className="flex flex-col flex-grow h-full overflow-hidden">
                    <SidebarGroup className="flex flex-col flex-grow h-full overflow-hidden">
                        <SidebarGroupLabel
                            className="text-lg font-bold text-white flex items-center justify-between gap-2 w-full">
                            <span>Termix / Terminal</span>
                            <button
                                type="button"
                                onClick={() => onCloseSidebar?.()}
                                title="Hide sidebar"
                                style={{
                                    height: 28,
                                    width: 28,
                                    display: 'inline-flex',
                                    alignItems: 'center',
                                    justifyContent: 'center',
                                    background: 'hsl(240 5% 9%)',
                                    color: 'hsl(240 5% 64.9%)',
                                    border: '1px solid hsl(240 3.7% 15.9%)',
                                    borderRadius: 6,
                                    cursor: 'pointer',
                                }}
                            >
                                <Menu className="h-4 w-4"/>
                            </button>
                        </SidebarGroupLabel>
                        <Separator className="p-0.25 mt-1 mb-1"/>
                        <SidebarGroupContent className="flex flex-col flex-grow h-full overflow-hidden">
                            <SidebarMenu className="flex flex-col flex-grow h-full overflow-hidden">

                                <SidebarMenuItem key="Homepage">
                                    <Button
                                        className="w-full mt-2 mb-2 h-8"
                                        onClick={() => onSelectView("homepage")}
                                        variant="outline"
                                    >
                                        <CornerDownLeft/>
                                        Return
                                    </Button>
                                    <Separator className="p-0.25 mt-1 mb-1"/>
                                </SidebarMenuItem>

                                <SidebarMenuItem key="Main" className="flex flex-col flex-grow overflow-hidden">
                                    <div
                                        className="w-full flex-grow rounded-md bg-[#09090b] border border-[#434345] overflow-hidden p-0 m-0 relative flex flex-col min-h-0">
                                        <div className="w-full px-2 pt-2 pb-2 bg-[#09090b] z-10">
                                            <Input
                                                value={search}
                                                onChange={e => setSearch(e.target.value)}
                                                placeholder="Search hosts by name, username, IP, folder, tags..."
                                                className="w-full h-8 text-sm bg-background border border-border rounded"
                                                autoComplete="off"
                                            />
                                        </div>
                                        <div style={{display: 'flex', justifyContent: 'center'}}>
                                            <Separator className="w-full h-px bg-[#434345] my-2"
                                                       style={{maxWidth: 213, margin: '0 auto'}}/>
                                        </div>
                                        {hostsError && (
                                            <div className="px-2 py-1 mt-2">
                                                <div
                                                    className="text-xs text-red-500 bg-red-500/10 rounded px-2 py-1 border border-red-500/20">{hostsError}</div>
                                            </div>
                                        )}
                                        <div className="flex-1 min-h-0">
                                            <ScrollArea className="w-full h-full">
                                                <Accordion key={`host-accordion-${sortedFolders.length}`}
                                                           type="multiple" className="w-full"
                                                           defaultValue={sortedFolders.length > 0 ? sortedFolders : undefined}>
                                                    {sortedFolders.map((folder, idx) => (
                                                        <React.Fragment key={folder}>
                                                            <AccordionItem value={folder}
                                                                           className={idx === 0 ? "mt-0 !border-b-transparent" : "mt-2 !border-b-transparent"}>
                                                                <AccordionTrigger
                                                                    className="text-base font-semibold rounded-t-none px-3 py-2"
                                                                    style={{marginTop: idx === 0 ? 0 : undefined}}>{folder}</AccordionTrigger>
                                                                <AccordionContent
                                                                    className="flex flex-col gap-1 px-3 pb-2 pt-1">
                                                                    {getSortedHosts(hostsByFolder[folder]).map(host => (
                                                                        <div key={host.id}
                                                                             className="w-full overflow-hidden">
                                                                            <HostMenuItem
                                                                                host={host}
                                                                                onHostConnect={onHostConnect}
                                                                            />
                                                                        </div>
                                                                    ))}
                                                                </AccordionContent>
                                                            </AccordionItem>
                                                            {idx < sortedFolders.length - 1 && (
                                                                <div
                                                                    style={{display: 'flex', justifyContent: 'center'}}>
                                                                    <Separator className="h-px bg-[#434345] my-1"
                                                                               style={{width: 213}}/>
                                                                </div>
                                                            )}
                                                        </React.Fragment>
                                                    ))}
                                                </Accordion>
                                            </ScrollArea>
                                        </div>
                                    </div>
                                </SidebarMenuItem>
                            </SidebarMenu>
                        </SidebarGroupContent>
                        <div className="bg-sidebar">
                            <Sheet open={toolsSheetOpen} onOpenChange={setToolsSheetOpen}>
                                <SheetTrigger asChild>
                                    <Button
                                        className="w-full h-8 mt-2"
                                        variant="outline"
                                        onClick={() => setToolsSheetOpen(true)}
                                    >
                                        <Hammer className="mr-2 h-4 w-4"/>
                                        Tools
                                    </Button>
                                </SheetTrigger>
                                <SheetContent side="left"
                                              className="w-[256px] fixed top-0 left-0 h-full z-[100] flex flex-col">
                                    <SheetHeader className="pb-0.5">
                                        <SheetTitle>Tools</SheetTitle>
                                    </SheetHeader>
                                    <div className="flex-1 overflow-y-auto px-2 pt-2">
                                        <Accordion type="single" collapsible defaultValue="multiwindow">
                                            <AccordionItem value="multiwindow">
                                                <AccordionTrigger className="text-base font-semibold">Run multiwindow
                                                    commands</AccordionTrigger>
                                                <AccordionContent>
                                                    <textarea
                                                        className="w-full min-h-[120px] max-h-48 rounded-md border border-input text-foreground p-2 text-sm font-mono resize-vertical focus:outline-none focus:ring-0"
                                                        placeholder="Enter command(s) to run on selected tabs..."
                                                        value={toolsCommand}
                                                        onChange={e => setToolsCommand(e.target.value)}
                                                        style={{
                                                            fontFamily: 'monospace',
                                                            marginBottom: 8,
                                                            background: '#141416'
                                                        }}
                                                    />
                                                    <div className="flex flex-wrap gap-2 mb-2">
                                                        {allTabs.map(tab => (
                                                            <Button
                                                                key={tab.id}
                                                                type="button"
                                                                variant={selectedTabIds.includes(tab.id) ? "secondary" : "outline"}
                                                                size="sm"
                                                                className="rounded-full px-3 py-1 text-xs flex items-center gap-1"
                                                                onClick={() => handleTabToggle(tab.id)}
                                                            >
                                                                {tab.title}
                                                            </Button>
                                                        ))}
                                                    </div>
                                                    <Button
                                                        className="w-full"
                                                        variant="outline"
                                                        onClick={handleRunCommand}
                                                        disabled={!toolsCommand.trim() || !selectedTabIds.length}
                                                    >
                                                        Run Command
                                                    </Button>
                                                </AccordionContent>
                                            </AccordionItem>
                                        </Accordion>

                                        <Separator className="p-0.25"/>

                                        <div className="flex items-center space-x-2 mt-5">
                                            <Checkbox id="enable-copy-paste" onCheckedChange={updateRightClickCopyPaste}
                                                      defaultChecked={getCookie("rightClickCopyPaste") === "true"}/>
                                            <label
                                                htmlFor="enable-paste"
                                                className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
                                            >
                                                Enable right‑click copy/paste
                                            </label>
                                        </div>
                                    </div>
                                </SheetContent>
                            </Sheet>
                        </div>
                    </SidebarGroup>
                </SidebarContent>
            </Sidebar>
        </SidebarProvider>
    );
}

const HostMenuItem = React.memo(function HostMenuItem({host, onHostConnect}: {
    host: SSHHost;
    onHostConnect: (hostConfig: any) => void
}) {
    const tags = Array.isArray(host.tags) ? host.tags : [];
    const hasTags = tags.length > 0;
    return (
        <div className="relative group flex flex-col mb-1 w-full overflow-hidden">
            <div className={`flex flex-col w-full rounded overflow-hidden border border-[#434345] bg-[#18181b] h-full`}>
                <div className="flex w-full h-10">
                    <div
                        className="flex items-center h-full px-2 w-full hover:bg-muted transition-colors cursor-pointer"
                        onClick={() => onHostConnect(host)}
                    >
                        <div className="flex items-center w-full">
                            {host.pin &&
                                <Pin className="h-4.5 mr-1 w-4.5 mt-0.5 text-yellow-500 flex-shrink-0"/>
                            }
                            <span className="font-medium truncate">{host.name || host.ip}</span>
                        </div>
                    </div>
                </div>
                {hasTags && (
                    <div
                        className="border-t border-border bg-[#18181b] flex items-center gap-1 px-2 py-2 overflow-x-auto overflow-y-hidden scrollbar-thin scrollbar-thumb-muted-foreground/30 scrollbar-track-transparent"
                        style={{height: 30}}>
                        {tags.map((tag: string) => (
                            <span key={tag}
                                  className="bg-muted-foreground/10 text-xs rounded-full px-2 py-0.5 text-muted-foreground whitespace-nowrap border border-border flex-shrink-0 hover:bg-muted transition-colors">
                                {tag}
                            </span>
                        ))}
                    </div>
                )}
            </div>
        </div>
    );
});