import React, { useReducer, Reducer } from 'react';
import { ThemeProvider, CssBaseline, createMuiTheme } from '@material-ui/core';
import { grey } from '@material-ui/core/colors';
import AppBar from './appbar/AppBar';
import QueryWindow from './windows/query/QueryWindow';
import { NewTabProps } from './appbar/AddTabMenu';
import { newWindowState, newWindowReducer, WindowType } from './windows/Windows';
import ArtistWindow from './windows/artist/ArtistWindow';
import AlbumWindow from './windows/album/AlbumWindow';
import TagWindow from './windows/tag/TagWindow';
import SongWindow from './windows/song/SongWindow';
import ManageTagsWindow from './windows/manage_tags/ManageTagsWindow';
var _ = require('lodash');

const darkTheme = createMuiTheme({
    palette: {
        type: 'dark',
        primary: {
            main: grey[100],
        }
    },
});

export interface MainWindowState {
    tabStates: any[],
    tabReducers: Reducer<any, any>[],
    tabTypes: WindowType[],
    activeTab: number,
}

export enum MainWindowStateActions {
    SetActiveTab = "setActiveTab",
    DispatchToTab = "dispatchToTab",
    CloseTab = "closeTab",
    AddTab = "addTab",
}

export function MainWindowReducer(state: MainWindowState, action: any) {
    switch (action.type) {
        case MainWindowStateActions.SetActiveTab:
            return { ...state, activeTab: action.value }
        case MainWindowStateActions.CloseTab:
            const newSize = state.tabStates.length - 1;
            return {
                ...state,
                tabStates: state.tabStates.filter((i: any, idx: number) => idx != action.idx),
                tabReducers: state.tabReducers.filter((i: any, idx: number) => idx != action.idx),
                tabTypes: state.tabTypes.filter((i: any, idx: number) => idx != action.idx),
                activeTab: state.activeTab >= (newSize - 1) ? (newSize - 1) : state.activeTab,
            }
        case MainWindowStateActions.AddTab:
            return {
                ...state,
                tabStates: [...state.tabStates, action.tabState],
                tabReducers: [...state.tabReducers, action.tabReducer],
                tabTypes: [...state.tabTypes, action.tabType],
            }
        case MainWindowStateActions.DispatchToTab:
            return {
                ...state,
                tabStates: state.tabStates.map((item: any, i: number) => {
                    return i === action.idx ?
                        state.tabReducers[i](item, action.tabAction) :
                        item;
                })
            }
        default:
            throw new Error("Unimplemented MainWindow state update.")
    }
}

export default function MainWindow(props: any) {
    const [state, dispatch] = useReducer(MainWindowReducer, {
        tabStates: [
            newWindowState[WindowType.Query](),
            newWindowState[WindowType.Song](),
            newWindowState[WindowType.Album](),
            newWindowState[WindowType.Artist](),
            newWindowState[WindowType.Tag](),
            newWindowState[WindowType.ManageTags](),
        ],
        tabReducers: [
            newWindowReducer[WindowType.Query],
            newWindowReducer[WindowType.Song],
            newWindowReducer[WindowType.Album],
            newWindowReducer[WindowType.Artist],
            newWindowReducer[WindowType.Tag],
            newWindowReducer[WindowType.ManageTags],
        ],
        tabTypes: [
            WindowType.Query,
            WindowType.Song,
            WindowType.Album,
            WindowType.Artist,
            WindowType.Tag,
            WindowType.ManageTags,
        ],
        activeTab: 0
    })

    const windows = state.tabStates.map((tabState: any, i: number) => {
        const tabDispatch = (action: any) => {
            dispatch({
                type: MainWindowStateActions.DispatchToTab,
                tabAction: action,
                idx: i
            });
        }

        switch (state.tabTypes[i]) {
            case WindowType.Query:
                return <QueryWindow
                    state={tabState}
                    dispatch={tabDispatch}
                    mainDispatch={dispatch}
                />
            case WindowType.Artist:
                return <ArtistWindow
                    state={tabState}
                    dispatch={tabDispatch}
                    mainDispatch={dispatch}
                />
            case WindowType.Album:
                return <AlbumWindow
                    state={tabState}
                    dispatch={tabDispatch}
                    mainDispatch={dispatch}
                />
            case WindowType.Tag:
                return <TagWindow
                    state={tabState}
                    dispatch={tabDispatch}
                    mainDispatch={dispatch}
                />
            case WindowType.Song:
                return <SongWindow
                    state={tabState}
                    dispatch={tabDispatch}
                    mainDispatch={dispatch}
                />
            case WindowType.ManageTags:
                return <ManageTagsWindow
                    state={tabState}
                    dispatch={tabDispatch}
                    mainDispatch={dispatch}
                />
            default:
                throw new Error("Unimplemented window type");
        }
    });

    return <ThemeProvider theme={darkTheme}>
        <CssBaseline />
        <AppBar
            tabLabels={state.tabStates.map((s: any) => s.tabLabel)}
            selectedTab={state.activeTab}
            setSelectedTab={(t: number) => dispatch({ type: MainWindowStateActions.SetActiveTab, value: t })}
            onCloseTab={(t: number) => dispatch({ type: MainWindowStateActions.CloseTab, idx: t })}
            onAddTab={(w: NewTabProps) => {
                dispatch({
                    type: MainWindowStateActions.AddTab,
                    tabState: newWindowState[w.windowType](),
                    tabReducer: newWindowReducer[w.windowType],
                    tabType: w.windowType,
                })
            }}
        />
        {windows[state.activeTab]}
    </ThemeProvider>
}