import { ListCheck, ListTodo } from 'lucide-react';
import { memo, useMemo, useState } from 'react';

import type { SubtaskFragmentFragment } from '@/graphql/types';

import Markdown from '@/components/shared/markdown';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';

import FlowTaskStatusIcon from './flow-task-status-icon';

interface FlowSubtaskProps {
    searchValue?: string;
    subtask: SubtaskFragmentFragment;
}

const containsSearchValue = (text: null | string | undefined, searchValue: string): boolean => {
    if (!text || !searchValue.trim()) {
        return false;
    }

    return text.toLowerCase().includes(searchValue.toLowerCase().trim());
};

function FlowSubtask({ searchValue = '', subtask }: FlowSubtaskProps) {
    const { description, id, result, status, title } = subtask;
    const [isDetailsVisible, setIsDetailsVisible] = useState(false);
    const hasDetails = description || result;

    const searchChecks = useMemo(() => {
        const trimmedSearch = searchValue.trim();

        if (!trimmedSearch) {
            return { hasDescriptionMatch: false, hasResultMatch: false };
        }

        return {
            hasDescriptionMatch: containsSearchValue(description, trimmedSearch),
            hasResultMatch: containsSearchValue(result, trimmedSearch),
        };
    }, [searchValue, description, result]);

    const [prevSearchValue, setPrevSearchValue] = useState(searchValue);
    const [prevHasMatch, setPrevHasMatch] = useState(searchChecks.hasDescriptionMatch || searchChecks.hasResultMatch);

    const hasMatch = searchChecks.hasDescriptionMatch || searchChecks.hasResultMatch;

    if (searchValue !== prevSearchValue || hasMatch !== prevHasMatch) {
        setPrevSearchValue(searchValue);
        setPrevHasMatch(hasMatch);

        const trimmedSearch = searchValue.trim();

        if (trimmedSearch) {
            if (hasMatch) {
                setIsDetailsVisible(true);
            }
        } else {
            setIsDetailsVisible(false);
        }
    }

    return (
        <div className="group relative flex gap-2.5 pb-4 pl-0.5">
            <FlowTaskStatusIcon
                className="bg-background ring-border ring-background relative z-1 mt-px rounded-full ring-3"
                status={status}
                tooltip={`Subtask ID: ${id}`}
            />
            <div className="flex flex-1 flex-col gap-2">
                <div className="text-sm">
                    <Markdown
                        className="prose-fixed prose-sm wrap-break-word *:m-0 [&>p]:leading-tight"
                        searchValue={searchValue}
                    >
                        {title}
                    </Markdown>
                </div>

                {hasDetails && (
                    <div className="text-muted-foreground text-xs">
                        <div
                            className="cursor-pointer hover:underline"
                            onClick={() => setIsDetailsVisible(!isDetailsVisible)}
                        >
                            {isDetailsVisible ? 'Hide details' : 'Show details'}
                        </div>
                        {isDetailsVisible && (
                            <div className="mt-4 flex flex-col gap-4">
                                {description && (
                                    <Card>
                                        <CardHeader className="p-3">
                                            <CardTitle className="flex items-center gap-2">
                                                <ListTodo className="size-4 shrink-0" /> Description
                                            </CardTitle>
                                        </CardHeader>
                                        <CardContent className="p-3 pt-0">
                                            <hr className="mt-0 mb-3" />
                                            <Markdown
                                                className="prose-xs prose-fixed wrap-break-word"
                                                searchValue={searchValue}
                                            >
                                                {description}
                                            </Markdown>
                                        </CardContent>
                                    </Card>
                                )}
                                {result && (
                                    <Card>
                                        <CardHeader className="p-3">
                                            <CardTitle className="flex items-center gap-2">
                                                <ListCheck className="size-4 shrink-0" /> Result
                                            </CardTitle>
                                        </CardHeader>
                                        <CardContent className="p-3 pt-0">
                                            <hr className="mt-0 mb-3" />
                                            <Markdown
                                                className="prose-xs prose-fixed wrap-break-word"
                                                searchValue={searchValue}
                                            >
                                                {result}
                                            </Markdown>
                                        </CardContent>
                                    </Card>
                                )}
                            </div>
                        )}
                    </div>
                )}
            </div>
            <div className="absolute top-0 left-[calc((--spacing(2.5))-0.5px)] h-full border-l group-last:hidden"></div>
        </div>
    );
}

export default memo(FlowSubtask);
