import "preact/debug";
import { get, post } from 'axios';
import { Component, render, Fragment, h } from 'preact';
import strftime from 'strftime';
import { ConfigView, Config } from './config.jsx'
/** @jsx h */
/** @jsxFrag Fragment */

/* naive. assumes:
    year = 365 days,
    day = 24 hrs,
    hr = 60 mins,
    min = 60 secs
*/
function format_relative_naive(date) {
    const sec = 1000;
    const min = 60 * sec;
    const hr = 60 * min;
    const day = 24 * hr;
    let now = new Date();
    let ms_diff = date - now;
    if (Math.abs(ms_diff) < 2 * min) {
        return `${Math.round(ms_diff / sec)}s`;
    } else if (Math.abs(ms_diff) < 2 * hr) {
        return `${Math.round(ms_diff / min)}m`;
    } else if (Math.abs(ms_diff) < 2 * day) {
        return `${Math.round(ms_diff / hr)}h`;
    } else {
        return `${Math.round(ms_diff / day)}d`;
    }
}


class TodoList extends Component {
    constructor() {
        super();
        this.state = { todos: [] };
    }

    componentWillMount() {
        get("/api/todos").then(resp => {
            let todos = resp.data.todos;
            todos.sort((todo1, todo2) => { return todo1.expires - todo2.expires; })
            this.setState({ todos: resp.data.todos })
        })
    }
    
    render({ config }, { todos }) {
        let { datefmt, timezoneOffset } = config;
        return <table class="table table-hover">
            <thead>
                <tr>
                    <td></td>
                    <td>what</td>
                    <td>when</td>
                    <td>left</td>
                </tr>
            </thead>
            <tbody>
                {todos.map(todo => {
                    return <TodoRow
                        dateFormatter={date => strftime("%H:%M", date)}
                        done={todo.done}
                        desc={todo.desc}
                        display_date={new Date(todo.expires)}
                        key={`todo-${todo.id}`}
                        id={todo.id}
                    />
                })}
            </tbody>
        </table>;
    }
}

class TodoRow extends Component {
    constructor(props) {
        super(props);
        this.state = { id: props.id }
    }

    deleteTodo(event) {
        post("/api/delete-todo", { id: this.state.id })
            .then(resp => {
                console.log(resp);
                window.location.reload();
            });
    }

    render({ dateFormatter, done, desc, display_date, key }, { }) {
        let status = done ?
                <span class="i">DONE</span>
            :   <span class="d"> TODO</span>
        return <tr key={key}>
            <td><i class="twa twa-heart"></i> {status}</td>
            <td>{desc}</td>
            <td>{dateFormatter(display_date)}</td>
            <td style={{textAlign: "right"}}>{format_relative_naive(display_date)}</td>
            <td><a class="a-button" onClick={this.deleteTodo.bind(this)}><i class="twa twa-cross-mark"></i></a></td>
        </tr>
    }
}

class PostForm extends Component {
    constructor({ notify_list, config }) {
        super();
        this.state = {
            notify_list: notify_list,
            desc: "",
            date: config.getDefaultDate() };
    }
    postTodo(event) {
        if (this.state.desc.length == 0) {
            return;
        }
        post(
            "/api/new-todo", {
                desc: this.state.desc,
                expires: new Date(this.state.date).getTime(),
                done: false
            }
        )
            .then((resp) => {
                console.log(resp.data);
                window.location.reload();
            }).catch((err) => {
                console.log("err: ");
                console.log(err);
            });
    }

    render(props, state) {
        let isEmpty = state.desc.length == 0;
        const noop = _ => {};
        let aClasslist = `a-button ${isEmpty ? "a-button-disabled" : ""}`
        return <>
            <input
                class="input-todo"
                type="text"
                onInput={e => this.setState({ desc: e.target.value })}
            />
            <input
                class="input-todo"
                type="text"
                onInput={e => this.setState({ date: e.target.value })}
                value={this.state.date}
            />
            <a class={aClasslist} onClick={isEmpty ? noop : this.postTodo.bind(this)}>post</a>
        </>
    }
}

class App extends Component {
    constructor() {
        super();
        this.state = { config: new Config() };
    }

    changeConfig(newConfig) {
        this.setState({ config: newConfig });
    }

    render({}, { config }) {
        return <div>
            <PostForm config={config} />
            <p style={{display: "inline"}}> | </p>
            <ConfigView config={config} onChangeConfig={this.changeConfig} />
            <TodoList config={config} />
        </div>
    }
}

render(<App />, document.getElementById("root"));
