import type React from "react";
import { useEffect, useState } from "react";
import {
    Accordion,
    AccordionButton,
    AccordionIcon,
    AccordionItem,
    AccordionPanel,
    Box,
    Link,
    Select,
    Table,
    Tag,
    Tbody,
    Td,
    Tr,
    Wrap,
    WrapItem,
} from "@chakra-ui/react";
import { Link as ReactRouterLink } from "react-router-dom";
import type { DetailResponse, RuntimeInfo } from "../app/services/problem";

const TitleItem = ({ word }: { word: string }) => (
    <h2>
        <AccordionButton>
            <Box as="span" flex="1" textAlign="left">
                {word}
            </Box>
            <AccordionIcon />
        </AccordionButton>
    </h2>
);

interface ProblemInfoMenuProps {
    data?: DetailResponse;
    onLanguageSelect?: (lang: string) => void;
    action?: React.ReactNode;
}

const EmptyRuntime: RuntimeInfo = {
    TimeLimit: 0,
    MemoryLimit: 0,
    NProcLimit: 0,
};

export default function ProblemInfoMenu(props: ProblemInfoMenuProps) {
    const [lang, setLang] = useState(props.data?.context.Languages[0]?.Lang || "c");
    const runtime = props.data?.context.Languages.find((x) => x.Lang === lang)?.Runtime.Run || EmptyRuntime;
    useEffect(() => {
        props.onLanguageSelect && props.onLanguageSelect(lang);
    }, [lang, props]);

    const problemInfo = (
        <Table variant="striped" size="sm">
            <Tbody>
                <Tr>
                    <Td>Title</Td>
                    <Td>{props.data?.problem.title || "..."}</Td>
                </Tr>
                <Tr>
                    <Td>Author</Td>
                    <Td>
                        <Link
                            as={ReactRouterLink}
                            color="blue.500"
                            to={`/profile/${props.data?.problem.provider.meta.ID || 0}`}
                        >
                            {props.data?.problem.provider.nick_name || "..."}
                        </Link>
                    </Td>
                </Tr>
                <Tr>
                    <Td>Languages</Td>
                    <Td>
                        <Wrap>
                            {props.data?.context.Languages.map((l) => (
                                <WrapItem key={l.Lang}>
                                    <Tag variant="outline" size="sm" colorScheme="pink">
                                        {l.Lang}
                                    </Tag>
                                </WrapItem>
                            ))}
                        </Wrap>
                    </Td>
                </Tr>
                <Tr>
                    <Td>Tags</Td>
                    <Td>
                        <Wrap>
                            {props.data?.problem.tags.Elements.map((t) => (
                                <WrapItem key={t}>
                                    <Tag variant="outline" size="sm" colorScheme="orange">
                                        {t}
                                    </Tag>
                                </WrapItem>
                            ))}
                        </Wrap>
                    </Td>
                </Tr>
            </Tbody>
        </Table>
    );

    const taskInfo = (
        <Table variant="striped" size="sm">
            <Tbody>
                <Tr>
                    <Td>Time Limit</Td>
                    <Td>{runtime.TimeLimit} ms</Td>
                </Tr>
                <Tr>
                    <Td>Memory Limit</Td>
                    <Td>{runtime.MemoryLimit} MB</Td>
                </Tr>
                <Tr>
                    <Td>Process Limit</Td>
                    <Td>{runtime.NProcLimit}</Td>
                </Tr>
                <Tr>
                    <Td>Select</Td>
                    <Td>
                        <Select size="sm" onChange={(e) => setLang(e.target.value)} value={lang}>
                            {props.data?.context.Languages.map((l) => (
                                <option key={l.Lang} value={l.Lang}>
                                    {l.Lang}
                                </option>
                            ))}
                        </Select>
                    </Td>
                </Tr>
            </Tbody>
        </Table>
    );

    return (
        <>
            <Accordion defaultIndex={[0, 1, ...(props.action ? [2] : [])]} allowMultiple>
                <AccordionItem>
                    <TitleItem word="Problem Info" />
                    <AccordionPanel pb={4}>{problemInfo}</AccordionPanel>
                </AccordionItem>

                <AccordionItem>
                    <TitleItem word="Task Info" />
                    <AccordionPanel pb={4}>{taskInfo}</AccordionPanel>
                </AccordionItem>

                {props.action && (
                    <AccordionItem>
                        <TitleItem word="Action" />
                        <AccordionPanel pb={4}>{props.action}</AccordionPanel>
                    </AccordionItem>
                )}
            </Accordion>
        </>
    );
}
