import { Button, InputNumber, Select, Popover } from "antd";
import { observer } from "mobx-react";
import React from "react";
import { AutoSizer, Column, Table, TableCellRenderer } from "react-virtualized";
import { huntOptimizerStore, WantedItem } from "../../stores/HuntOptimizerStore";
import { itemStore } from "../../stores/ItemStore";
import './WantedItemsComponent.less';

@observer
export class WantedItemsComponent extends React.Component {
    state = {
        helpVisible: false
    }

    render() {
        // Make sure render is called on updates.
        huntOptimizerStore.wantedItems.slice(0, 0);

        return (
            <section className="ho-WantedItemsComponent">
                <h3>
                    Wanted Items
                    <Popover
                        content={<Help />}
                        trigger="click"
                        visible={this.state.helpVisible}
                        onVisibleChange={this.onHelpVisibleChange}
                    >
                        <Button icon="info-circle" type="link" />
                    </Popover>
                </h3>
                <div>
                    <Select
                        value={undefined}
                        showSearch
                        placeholder="Add an item"
                        optionFilterProp="children"
                        style={{ width: 200 }}
                        filterOption
                        onChange={this.addWanted}
                    >
                        {itemStore.items.current.value.map(item => (
                            <Select.Option key={item.name}>
                                {item.name}
                            </Select.Option>
                        ))}
                    </Select>
                    <Button
                        onClick={huntOptimizerStore.optimize}
                        style={{ marginLeft: 10 }}
                    >
                        Optimize
                     </Button>
                </div>
                <div className="ho-WantedItemsComponent-table">
                    <AutoSizer>
                        {({ width, height }) => (
                            <Table
                                width={width}
                                height={height}
                                headerHeight={30}
                                rowHeight={30}
                                rowCount={huntOptimizerStore.wantedItems.length}
                                rowGetter={({ index }) => huntOptimizerStore.wantedItems[index]}
                                noRowsRenderer={this.noRowsRenderer}
                            >
                                <Column
                                    label="Amount"
                                    dataKey="amount"
                                    width={70}
                                    cellRenderer={({ rowData }) =>
                                        <WantedAmountCell wantedItem={rowData} />
                                    }
                                />
                                <Column
                                    label="Item"
                                    dataKey="item"
                                    width={150}
                                    flexGrow={1}
                                    cellDataGetter={({ rowData }) => rowData.item.name}
                                />
                                <Column
                                    dataKey="remove"
                                    width={30}
                                    cellRenderer={this.tableRemoveCellRenderer}
                                />
                            </Table>
                        )}
                    </AutoSizer>
                </div>
            </section>
        );
    }

    private addWanted = (itemName: string) => {
        let added = huntOptimizerStore.wantedItems.find(w => w.item.name === itemName);

        if (!added) {
            const item = itemStore.items.current.value.find(i => i.name === itemName)!;
            huntOptimizerStore.wantedItems.push(new WantedItem(item, 1));
        }
    }

    private removeWanted = (wanted: WantedItem) => () => {
        const i = huntOptimizerStore.wantedItems.findIndex(w => w === wanted);

        if (i !== -1) {
            huntOptimizerStore.wantedItems.splice(i, 1);
        }
    }

    private tableRemoveCellRenderer: TableCellRenderer = ({ rowData }) => {
        return <Button type="link" icon="delete" onClick={this.removeWanted(rowData)} />;
    }

    private noRowsRenderer = () => {
        return (
            <div className="ho-WantedItemsComponent-no-rows">
                <p>
                    Add some items with the above drop down and click "Optimize" to see the result on the right.
                </p>
            </div>
        );
    }

    private onHelpVisibleChange = (visible: boolean) => {
        this.setState({ helpVisible: visible });
    }
}

function Help() {
    return (
        <div className="ho-WantedItemsComponent-help">
            <p>
                Add some items with the drop down and click "Optimize" to see the optimal set of method/difficulty/section ID combinations on the right.
            </p>
            <p>
                At the moment a method is simply a quest run-through. Partial quest run-throughs are coming. View the list of methods on the "Methods" tab. Each method takes a certain amount of time, which affects the optimization result. Make sure the times are correct for you (at the moment times can't be changed, but this feature is coming).
            </p>
            <p>
                Only enemy drops are considered. Box drops are coming.
            </p>
            <p>
                The optimal result is calculated using linear optimization. The optimizer takes rare enemies and the fact that pan arms can be split in two into account.
            </p>
        </div>
    )
}

@observer
class WantedAmountCell extends React.Component<{ wantedItem: WantedItem }> {
    render() {
        const wanted = this.props.wantedItem;

        return (
            <InputNumber
                min={0}
                max={10}
                value={wanted.amount}
                onChange={this.wantedAmountChanged}
                size="small"
                style={{ width: '100%' }}
            />
        );
    }

    private wantedAmountChanged = (value?: number) => {
        if (value != null && value >= 0) {
            this.props.wantedItem.amount = value;
        }
    }
}
