import {Topic, topicsCtx} from "@/contexts/topics";
import {Layout} from "../layout";
import {Spinner} from "../spinner";
import style from "./style.module.scss";
import {Button} from "../button";
import {Input} from "../input";
import {Clipboard, Trash2} from "preact-feather";
import {useContext, useEffect, useMemo, useRef, useState} from "preact/hooks";
import {frenchToIso8601, iso8601ToFrench} from "@/utils/dates";
import {FormGroup} from "../form";
import {Slider} from "../slider";
import cn from "classnames";
import {routeCtx, routes} from "@/contexts/route";
import {settingsCtx} from "@/contexts/settings";
import {Wysiwyg} from "@/components/wysiwyg";
import {Alert} from "@/components/alert";
import {logCtx} from "@/contexts/log";
import {Pagination} from "@/components/pagination";

const topicsPerPage = 10;

export function Topics(props: {
    page: number,
    setPage: (newPage: number) => void,
}) {
    const [importContent, setImportContent] = useState("");
    const [topicsContext, setTopicsContext, topicsActions] = useContext(topicsCtx);
    const [, , logActions] = useContext(logCtx);
    const [settings, setSettings] = useContext(settingsCtx);

    useEffect(() => {
        if((topicsPerPage * props.page) >= topicsContext.topics.length) {
            props.setPage(Math.ceil(topicsContext.topics.length / topicsPerPage)/* - 1*/);
        }
    }, [topicsContext.topics.length])

    const sortedTopics = useMemo(() => {
        return [...topicsContext.topics].sort((topicA, topicB) => {
            if (topicA.posts.length < 1 || topicB.posts.length < 1) {
                return 0;
            }
            return topicB.posts[topicB.posts.length - 1].date.localeCompare(topicA.posts[topicA.posts.length - 1].date);
        });
    }, [topicsContext.topics]);

    const sortedTopicsSlice = useMemo(
        () => sortedTopics.slice(props.page * topicsPerPage, (props.page + 1) * topicsPerPage),
        [props.page, sortedTopics]
    );

    const pendingGeneration = topicsContext.generation === "pending";

    return (
        <div>
            <div className={style.listWrapper}>
                <Pagination
                    pageCount={Math.ceil(sortedTopics.length / topicsPerPage)}
                    page={props.page}
                    setPage={props.setPage}
                />
                <List topics={sortedTopicsSlice}/>
                <Pagination
                    pageCount={Math.ceil(sortedTopics.length / topicsPerPage)}
                    page={props.page}
                    setPage={props.setPage}
                />
            </div>
            <div>
                <h2>Nouveau sujet</h2>
                <Alert
                    lines={
                        topicsContext.generation === "error" ? [
                            "Erreur lors de la génération du topic",
                            "Veuillez regarder le log pour plus d'informations"
                        ] : []
                    }
                />
                <div className={style.generationSettings}>
                    <FormGroup>
                        <label for="postCount">Nombre de posts</label>
                        <Slider
                            name="postCount"
                            value={settings.postCount}
                            onChange={(v) => setSettings({...settings, postCount: v})}
                            min={1}
                            max={10}
                            step={1}
                        />
                    </FormGroup>
                </div>
                <Button
                    onClick={() => {
                        topicsActions.generateTopic(settings, logActions.log)
                    }}
                    secondary={true}
                    loading={pendingGeneration}
                >
                    {pendingGeneration ? "Génération en cours…" : "Générer"}
                </Button>
            </div>
            <hr/>
            <div>
                <Wysiwyg
                    showTitle={true}
                    onSubmit={(user, title, text) => {
                        // setLastAddedTopicId(topicsActions.addTopic(user, title, text));
                        topicsActions.addTopic(user, title, text)
                        props.setPage(0);
                        window.scrollTo({top: 0, behavior: 'smooth'});
                    }}
                    disabled={pendingGeneration}
                />
            </div>
            <hr/>
            <div>
                <Alert
                    lines={
                        topicsContext.import === "error" ? [
                            "Erreur lors de l'importation du sujet",
                        ] : []
                    }
                />
                <div className={style.import}>
                    <textarea
                        placeholder="Importer un sujet…"
                        name="import"
                        id="import"
                        cols="30"
                        rows="10"
                        value={importContent}
                        onInput={(e) => setImportContent((e.target as HTMLTextAreaElement).value)}
                    />
                </div>
                <Button
                    onClick={() => {
                        topicsActions.importTopic(importContent);
                        setImportContent("");
                    }}
                    secondary={true}
                >
                    Importer
                </Button>
            </div>
        </div>
    )
}

function List(props: {
    topics: Topic[],
    // latestGeneratedTopicId: string | null,
}) {
    return (
        <ul className={style.list}>
            <li className={style.head}>
                <span>Sujet</span>
                <span>Auteur</span>
                <span>NB</span>
                <span>Dernier msg</span>
                <span></span>
            </li>
            {props.topics.length < 1 && <li><span>Aucun sujet</span><span/><span/><span/><span/></li>}
            {props.topics.map(topic => <TopicElement topic={topic}/>)}
        </ul>
    )
}

function TopicElement(props: {
    topic: Topic;
}) {
    const topic = props.topic;
    const [, setRoute] = useContext(routeCtx);
    const [, , topicsActions] = useContext(topicsCtx);

    let isRecent: boolean = false;
    if (topic.posts.length > 0) {
        const firstPost = topic.posts[0];
        const dateDelta = new Date() - new Date(firstPost.generationDate || firstPost.date); // difference in ms

        // If the topic is more recent than 3 sec
        if (dateDelta < 3000) {
            isRecent = true;
        }
    }

    return (
        <li className={cn({[style.highlight]: isRecent})}>
                    <span>
                        <a href={routes.topic(topic.id, 1).location} onClick={(e) => {
                            e.preventDefault();
                            setRoute(routes.topic(topic.id, 1));
                        }}>
                            {topic.title}
                        </a>
                    </span>
            <span>{topic.posts[0].user}</span>
            <span>{topic.posts.length}</span>
            <span>{iso8601ToFrench(topic.posts[topic.posts.length - 1].date)}</span>
            <span>
                <span title="Copier le sujet">
                    <Clipboard
                        size={16}
                        className={style.clipboard}
                        onClick={() => {
                            const json = JSON.stringify(topic);
                            navigator.clipboard.writeText(json);
                        }}
                    />
                </span>
                <span title="Supprimer le sujet">
                    <Trash2
                        size={16}
                        className={style.trash}
                        onClick={() => topicsActions.deleteTopic(topic.id)}
                    />
                </span>
            </span>
        </li>
    )
}