/**
 * Copyright (c) 2021 lingdocs.com
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 */

import { useEffect, useState } from "react";
import ConjugationViewer from "./components/ConjugationViewer";
import verbs from "./verbs";
import Pashto from "./components/Pashto";
import Phonetics from "./components/Phonetics";
import InlinePs from "./components/InlinePs";
import { conjugateVerb } from "./lib/verb-conjugation";
import { getVerbInfo } from "./lib/verb-info";
import ButtonSelect from "./components/ButtonSelect";
import {
    clamp
} from "./lib/p-text-helpers";
import {
    randomNumber,
} from "./lib/misc-helpers";
import {
    Modal
} from "react-bootstrap";
import * as T from "./types";
import defualtTextOptions from "./lib/default-text-options";

type VerbType = "simple" | "stative compound" | "dynamic compound";
const verbTypes: VerbType[] = [
    "simple",
    "stative compound",
    "dynamic compound",
];

const transitivities: T.Transitivity[] = [
    "transitive",
    "intransitive",
    "grammatically transitive",
];

const allVerbs = verbs.map((v: { entry: T.DictionaryEntry, complement?: T.DictionaryEntry }) => ({
    verb: v,
    info: getVerbInfo(v.entry, v.complement),
}));

function App() {
    const [verbTs, setVerbTs] = useState<number>(0);
    const [verbTypeShowing, setVerbTypeShowing] = useState<VerbType>("simple");
    const [regularIrregular, setRegularIrregular] = useState<"regular" | "irregular">("regular");
    const [transitivityShowing, setTransitivityShowing] = useState<T.Transitivity>("intransitive");
    const [showingTextOptions, setShowingTextOptions] = useState<boolean>(false);
    const [textOptions, setTextOptions] = useState<T.TextOptions>(defualtTextOptions);
    const [aayTailType, setAayTailType] = useState<T.AayTail>("aay");
    const [theme, setTheme] = useState<"light" | "dark">("light");
    // const onlyGrammTrans = (arr: Transitivity[]) => (
    //     arr.length === 1 && arr[0] === "grammatically transitive"
    // );
    // const ensureSimpleVerbTypeSelected = () => {
    //     if (!verbTypesShowing.includes["simple"]) {
    //         setVerbTypesShowing([...verbTypesShowing, "simple"]);
    //     }
    // }

    useEffect(() => {
        const verbTsRaw = localStorage.getItem("verbTs");
        const verbTypeShowing = localStorage.getItem("verbTypeShowing") as undefined | VerbType;
        const regularIrregular = localStorage.getItem("regularIrregular") as "regular" | "irregular";
        const transitivitiyShowing = localStorage.getItem("transitivityShowing") as undefined | T.Transitivity;
        const theme = localStorage.getItem("theme");
        const textOptionst = localStorage.getItem("textOptions");
        const aayTailType = localStorage.getItem("aayType");
        if (regularIrregular) {
            setRegularIrregular(regularIrregular);
        }
        if (verbTsRaw) {
            setVerbTs(JSON.parse(verbTsRaw));
        }
        if (verbTypeShowing) {
            setVerbTypeShowing(verbTypeShowing);
        }
        if (transitivitiyShowing) {
            setTransitivityShowing(transitivitiyShowing);
        }
        if (theme) {
            setTheme(theme as "light" | "dark");
        }
        if (window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches) {
            setTheme("dark");
        }
        if (textOptionst) {
            setTextOptions(JSON.parse(textOptionst) as T.TextOptions);
        }
        if (aayTailType) {
            setAayTailType(aayTailType as T.AayTail);
        }
    }, []);

    useEffect(() => {
        localStorage.setItem("verbTs", verbTs.toString());
        localStorage.setItem("regularIrregular", regularIrregular);
        localStorage.setItem("verbTypeShowing", verbTypeShowing);
        localStorage.setItem("transitivityShowing", transitivityShowing);
        localStorage.setItem("textOptions", JSON.stringify(textOptions));
        localStorage.setItem("theme", theme);
        localStorage.setItem("aayType", aayTailType);
    });

    useEffect(() => {
        document.documentElement.setAttribute("data-theme", theme);
    }, [theme])

    const handleVerbIndexChange = (e: any) => {
        console.log("changing to", e.target.value);
        setVerbTs(parseInt(e.target.value));
    }
    const handleTypeSelection = (e: any) => {
        const type = e.target.value as VerbType;
        if (type === "dynamic compound") {
            setTransitivityShowing("transitive");
        }
        if (type === "stative compound" && transitivityShowing === "grammatically transitive") {
            setTransitivityShowing("transitive");
        }
        setVerbTypeShowing(type);
    }
    const handleTransitivitySelection = (e: any) => {
        const transitivity = e.target.value as T.Transitivity;
        if (transitivity === "grammatically transitive") {
            setVerbTypeShowing("simple");
        }
        setTransitivityShowing(e.target.value as T.Transitivity);
    }
    const isRegularVerb = (entry: T.DictionaryEntry): boolean => (
        !entry.l && !entry.psp && !entry.ssp && !entry.prp && !entry.pprtp && !entry.noOo && !entry.sepOo
    );
    const verbsAvailable = allVerbs.filter((verb) => (
        (
            (verb.info.type === "transitive or grammatically transitive simple" && verbTypeShowing === "simple") && (transitivityShowing === "transitive" || transitivityShowing === "grammatically transitive")
        ) ||
        ((
            verbTypeShowing === verb.info.type || 
            (verbTypeShowing === "stative compound" && verb.info.type === "dynamic or stative compound") ||
            (verbTypeShowing === "dynamic compound" && verb.info.type === "dynamic or stative compound") ||
            (verbTypeShowing === "dynamic compound" && verb.info.type === "dynamic or generative stative compound") ||
            (verbTypeShowing === "stative compound" && verb.info.type === "dynamic or generative stative compound")
        )
        && (
            transitivityShowing === verb.info.transitivity
        ))
    )).filter((verb) => {
        if (verbTypeShowing !== "simple") {
            return true;
        }
        return regularIrregular === "regular"
            ? isRegularVerb(verb.verb.entry)
            : !isRegularVerb(verb.verb.entry);
    }).sort((a, b) => a.verb.entry.p.localeCompare(b.verb.entry.p, "ps"));

    const v = (() => {
        const vFound = verbsAvailable.find(v => v.verb.entry.ts === verbTs);
        if (vFound) return vFound;
        if (verbsAvailable.length === 0) return undefined;
        const vTopOfList = verbsAvailable[0];
        setVerbTs(vTopOfList.verb.entry.ts);
        return vTopOfList;
    })();

    const pickRandomVerb = () => {
        let newIndex: number;
        do {
          newIndex = randomNumber(0, verbsAvailable.length);
        } while(verbsAvailable[newIndex].verb.entry.ts === verbTs);
        setVerbTs(verbsAvailable[newIndex].verb.entry.ts);
    };
    const makeVerbLabel = (entry: T.DictionaryEntry): string => (
        `${entry.p} - ${clamp(entry.e, 20)}`
    );

    const conjugation = v
        ? conjugateVerb(v.verb.entry, aayTailType, v.verb.complement)
        : undefined;
    // if (v) {
    //     console.log("Verb chosen:");
    //     console.log(v.verb);
    //     console.log("Conjugation of verb:")
    //     console.log(conjugation);
    // }
    return <>
        <main className="flex-shrink-0 mb-4">
            <div className="container" style={{ maxWidth: "800px" }}>
            <div style={{ position: "absolute", top: "1.5rem", right: "1.5rem", display: "flex", flexDirection: "row" }}>
                <div
                    className="clickable mr-3"
                    onClick={() => setShowingTextOptions(true)}
                >
                    <i className="fa-lg fas fa-cog" />
                </div>
                <div
                    className="clickable"
                    onClick={() => setTheme(theme === "light" ? "dark" : "light")}
                >
                    <i className={`fa-lg fas fa-${theme === "light" ? "sun" : "moon"}`} />
                </div>
            </div>
                <div className="text-center" style={{ marginTop: "3rem", marginBottom: "1rem" }}>
                    <h1 className="display-4 mt-2">Pashto Verb Explorer</h1>
                    <p>by <a href="https://www.lingdocs.com">LingDocs</a></p>
                    <p className="lead my-4">
                        Each form is made from one simple <samp>formula</samp> which <a href="https://www.lingdocs.com/blog/pashto-verbs-master-chart">works for all verbs</a>. 👨‍🔬
                    </p>
                    <p>Choose a verb 👇, look at its roots and stems 🌳, see how all the forms are made and what they mean. 🤓</p>
                </div>
                <div className="d-block mx-auto card" style={{ maxWidth: "700px", background: "var(--closer)"}}>
                    <div className="card-body">
                        <div className="row">
                            <div className="col-sm-6">
                                {(v && conjugation) ?
                                    <div>
                                        <div className="mb-1">Select a verb:</div>
                                        <div className="input-group">
                                            <select className="custom-select" value={verbTs} onChange={handleVerbIndexChange}>
                                                {verbsAvailable.length
                                                    ? verbsAvailable.map((v, i) => (
                                                        <option value={v.verb.entry.ts} key={i} dir="ltr">
                                                            {"\u200E"}{makeVerbLabel(v.verb.entry)}
                                                        </option>
                                                    ))
                                                    : <option>Select a verb type</option>
                                                }
                                            </select>
                                            <div className="input-group-append">
                                                <button className="btn btn-secondary" onClick={pickRandomVerb}>
                                                    <i className="fas fa-random" />
                                                </button>
                                            </div>
                                        </div>
                                        <div className="my-3">
                                            <div>
                                                <strong>
                                                    <Pashto opts={textOptions}>{v.verb.entry}</Pashto> 
                                                    {` `}-{` `}
                                                    <Phonetics opts={textOptions}>{v.verb.entry}</Phonetics>
                                                </strong>
                                                {` `}
                                                <em>{v.verb.entry.c}</em>
                                            </div>
                                            <div className="ml-3">{v.verb.entry.e}</div>
                                        </div>
                                    </div>
                                    : <div className="alert alert-warning mb-4" role="alert">
                                        No such verbs available...
                                    </div>
                                }
                            </div>
                            <div className="col-sm-6">
                                <h6>Verb type:</h6>
                                <div onChange={handleTypeSelection}>
                                    {verbTypes.map((type) => (
                                        <div key={type} className="form-check">
                                            <input 
                                                className="form-check-input" 
                                                type="radio"
                                                name="verb-type"
                                                checked={verbTypeShowing === type}
                                                value={type}
                                            />
                                            <label className="form-check-label">
                                                {type}
                                            </label>
                                        </div>
                                    ))}
                                </div>
                                {verbTypeShowing === "simple" &&
                                    <div className="mt-2">
                                        <ButtonSelect
                                            small
                                            options={[
                                                { label: "regular", value: "regular" },
                                                { label: "irregular", value: "irregular" },
                                            ]}
                                            value={regularIrregular}
                                            handleChange={(p) => {
                                                setRegularIrregular(p as "regular" | "irregular");
                                            }}
                                        />
                                    </div>
                                }
                                <h6 className="mt-2">Transitivity:</h6>
                                <div onChange={handleTransitivitySelection}>
                                    {transitivities.map((transitivity) => (
                                        <div key={transitivity} className="form-check">
                                            <input 
                                                className="form-check-input" 
                                                type="radio"
                                                name="transitivity"
                                                checked={transitivityShowing === transitivity}
                                                value={transitivity} 
                                            />
                                            <label className="form-check-label">
                                                {transitivity}
                                            </label>
                                        </div>
                                    ))}
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
                {conjugation && <ConjugationViewer
                    conjugation={conjugation}
                    textOptions={textOptions}
                    ec={v ? v.verb.entry.ec : undefined}
                />}
            </div>
        </main>
        <Modal show={showingTextOptions} onHide={() => setShowingTextOptions(false)}>
            <Modal.Header closeButton>
            <Modal.Title>Settings</Modal.Title>
            </Modal.Header>
            <Modal.Body>
                <h6>Pashto Spelling</h6>
                <ButtonSelect
                    options={[
                        { label: "🇦🇫 Afghan", value: "Afghan" },
                        { label: "🇵🇰 Pakistani", value: "Pakistani" },
                    ]}
                    value={textOptions.spelling}
                    handleChange={(p) => {
                        setTextOptions({
                            ...textOptions,
                            spelling: p as "Afghan" | "Pakistani",
                        });
                        if (p === "Pakistani") setAayTailType("ey");
                    }}
                />
                {textOptions.spelling !== "Pakistani" && <>
                    <h6 className="mt-3">Non-Inflecting Tail Spelling</h6>
                    <ButtonSelect
                        options={[
                            { label: <InlinePs opts={textOptions}>{{ p: "ی", f: "ey" }}</InlinePs>, value: "ey" },
                            { label: <InlinePs opts={textOptions}>{{ p: "ای", f: "aay" }}</InlinePs>, value: "aay" },
                        ]}
                        value={aayTailType}
                        handleChange={(p) => setAayTailType(p as "ey" | "aay")}
                    />
                </>}
                <h6 className="mt-3">Diacritics</h6>
                <ButtonSelect
                    options={[
                        { label: "On", value: "true" },
                        { label: "Off", value: "false" },
                    ]}
                    value={textOptions.diacritics.toString()}
                    handleChange={(p) => setTextOptions({ ...textOptions, diacritics: p === "true" })}
                />
                <h6 className="mt-3">Pashto Text Size</h6>
                <ButtonSelect
                    options={[
                        { label: "Normal", value: "normal" },
                        { label: "Large", value: "larger" },
                        { label: "X-Large", value: "largest" },
                    ]}
                    value={textOptions.pTextSize}
                    handleChange={(p) => setTextOptions({ ...textOptions, pTextSize: p as "normal" | "larger" | "largest" })}
                />
                <h6 className="mt-3">Phonetics</h6>
                <ButtonSelect
                    options={[
                        { label: "LingDocs", value: "lingdocs" },
                        { label: "IPA", value: "ipa" },
                        { label: "ALAC", value: "alalc" },
                        { label: "None", value: "none" },
                    ]}
                    value={textOptions.phonetics}
                    handleChange={(p) => setTextOptions({ ...textOptions, phonetics: p as "lingdocs" | "ipa" | "none" | "alalc" })}
                />
            </Modal.Body>
            <Modal.Footer>
                <button type="button" className="btn btn-primary clb" onClick={() => setShowingTextOptions(false)}>
                    Close
                </button>
            </Modal.Footer>
        </Modal>
        <footer className="footer mt-auto py-3" style={{ backgroundColor: "#f5f5f5" }}>
            <div className="container">
                <span className="text-muted">Copyright © 2020 <a href="https://www.lingdocs.com">lingdocs.com</a> all rights reserverd</span>
            </div>
        </footer>
    </>
}

export default App;
