/* eslint-disable jsx-a11y/anchor-is-valid */
import {
    Box,
    Button,
    Dialog,
    DialogActions,
    DialogContent,
    Divider,
    FormControl,
    FormControlLabel,
    Grid,
    Link,
    Switch,
    Typography
} from '@material-ui/core'
import { shell } from 'electron'
import { ipcRenderer as ipc } from 'electron-better-ipc'
import path from 'path'
import * as React from 'react'
import { Redirect } from 'react-router-dom'
import infoIcon from 'space-eye-icons/dist/info_app.png'
import styled from 'styled-components'

import {
    GET_AUTO_UPDATE,
    GET_START_ON_LOGIN,
    QUIT_APPLICATION_CHANNEL,
    SET_AUTO_UPDATE,
    SET_START_ON_LOGIN
} from '../../shared/IpcDefinitions'

const SectionsContainer = styled.div`
    display: flex;
    flex-direction: row;
    flex-grow: 1;
    flex-basis: var(--sections-column-width);
    align-items: flex-start;
    justify-content: flex-end;
    background-color: rgb(48, 48, 48);
`

const SectionsColumn = styled.div`
    display: flex;
    flex-direction: column;
    width: var(--sections-column-width);
    height: 100%;
`

const SettingsColumn = styled.div`
    flex-grow: 1;
    flex-basis: 400px;
`

const Row = styled.div`
    display: flex;
    flex-direction: row;
`

const ProductTitle = styled.h1`
    font-family: Roboto, sans-serif;
    font-size: 25px;
    font-weight: normal;
    letter-spacing: 0.15px;
    color: white;
`

const SettingsHeader = styled.h2`
    font-family: Roboto, sans-serif;
    font-size: 20px;
    font-weight: normal;
    letter-spacing: 0.15px;
    color: white;
`

const Spacer = styled.div`
    flex-grow: 1;
`

const SettingsContainer = styled.div`
    --top-padding: 75px;
    --sections-column-width: 200px;
    --settings-column-width: 400px;
    display: flex;
    flex-direction: row;
    height: 100%;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
    position: absolute;
`

const QuitButton = styled.button`
    text-decoration: none;
    appearance: none;
    outline: none;
    cursor: pointer;
    margin: 20px 0;
    background: transparent;
    border: 1px solid red;
    border-radius: 5px;
    color: red;
    padding: 8px 17px;
    font-family: Roboto, sans-serif;
    font-size: 16px;
    font-weight: normal;
    letter-spacing: 0.15px;
`

const BackButton = styled.button`
    --button-color: #0075ff;
    text-decoration: none;
    appearance: none;
    outline: none;
    cursor: pointer;
    margin: 20px 0;
    background: transparent;
    border-width: 1px;
    border-style: solid;
    border-radius: 5px;
    border-color: var(--button-color);
    color: var(--button-color);
    padding: 8px 17px;
    font-family: Roboto, sans-serif;
    font-size: 16px;
    font-weight: normal;
    letter-spacing: 0.15px;
`

interface SettingsSwitchProps {
    label: string
    isChecked: boolean
    onChange: (isChecked: boolean) => void
}

const SettingsSwitch: React.FC<SettingsSwitchProps> = props => {
    const { label, isChecked, onChange } = props
    return (
        <FormControl component="fieldset">
            <FormControlLabel
                control={
                    <Switch
                        checked={isChecked}
                        onChange={(_, checked) => onChange(checked)}
                        name={label}
                        color="primary"
                    />
                }
                label={label}
                labelPlacement="top"
            />
        </FormControl>
    )
}

const AppIcon = styled.img`
    width: 70px;
    height: 70px;
    margin-left: auto;
    margin-right: auto;
`

interface AboutThisAppProps {
    onClickDone: () => void
    visible: boolean
}

const AboutThisApp: React.FC<AboutThisAppProps> = props => {
    return (
        <Dialog open={props.visible} style={{ userSelect: 'none', textAlign: 'center' }}>
            <DialogContent>
                <AppIcon src={infoIcon} alt="SpaceEye icon" />
                <Typography variant="h6">SpaceEye</Typography>
                <Typography variant="body2" style={{ userSelect: 'text' }}>
                    Version {APP_VERSION}
                </Typography>
                <Typography variant="body2">Copyright &copy; 2020 Michael Galliers</Typography>
                <Typography variant="body2">License: {APP_LICENSE}</Typography>
                <Link
                    component="button"
                    variant="body2"
                    onClick={() => shell.openExternal(APP_BUGS_URL)}
                >
                    Report bugs
                </Link>
                <DialogActions>
                    <Button
                        onClick={() =>
                            shell.openPath(path.join(process.resourcesPath, 'legal_notices.txt'))
                        }
                    >
                        Acknowledgements
                    </Button>
                    <Button onClick={props.onClickDone}>Done</Button>
                </DialogActions>
            </DialogContent>
        </Dialog>
    )
}

interface SettingsProps {
    onClickBack: () => void
    onClickQuit: () => void
    onClickStartOnLoginSwitch: (shouldStart: boolean) => void
    onClickAutoUpdateSwitch: (autoUpdate: boolean) => void
    openAboutApp: () => void
    closeAboutApp: () => void
    shouldStartOnLogin: boolean
    autoUpdate: boolean
    aboutAppVisible: boolean
}

const Settings: React.FC<SettingsProps> = props => {
    const {
        onClickBack,
        onClickQuit,
        onClickStartOnLoginSwitch,
        onClickAutoUpdateSwitch,
        openAboutApp,
        closeAboutApp,
        shouldStartOnLogin,
        autoUpdate,
        aboutAppVisible
    } = props

    return (
        <SettingsContainer>
            <SectionsContainer>
                <SectionsColumn>
                    <Box my={1} />
                    <Grid container direction="row" justify="center">
                        <Typography variant="h5">SpaceEye</Typography>
                    </Grid>
                    <Box my={1} />
                    <Grid container direction="row" justify="center">
                        <Button variant="outlined" color="primary" onClick={onClickBack}>
                            Back
                        </Button>
                    </Grid>
                    <Spacer />
                    <Grid container direction="column" justify="center" alignItems="center">
                        <Link
                            component="button"
                            variant="body2"
                            color="textSecondary"
                            onClick={openAboutApp}
                        >
                            About
                        </Link>
                        <Box my={0.5} />
                        <Button variant="outlined" color="secondary" onClick={onClickQuit}>
                            Quit
                        </Button>
                    </Grid>
                    <Box my={1} />
                </SectionsColumn>
            </SectionsContainer>
            <SettingsColumn>
                <Box my={2} />
                <Grid container direction="row" justify="center">
                    <Typography variant="h6">Settings</Typography>
                </Grid>
                <Box my={2} mx={1}>
                    <Divider variant="fullWidth" />
                </Box>
                <Grid container direction="column" justify="flex-start" alignContent="flex-start">
                    <SettingsSwitch
                        isChecked={shouldStartOnLogin}
                        onChange={onClickStartOnLoginSwitch}
                        label="Start on Login"
                    />
                    {/* Don't show auto-update option if downloaded from an app store */}
                    {!process.mas && !process.windowsStore && (
                        <SettingsSwitch
                            isChecked={autoUpdate}
                            onChange={onClickAutoUpdateSwitch}
                            label="Auto update"
                        />
                    )}
                </Grid>
            </SettingsColumn>
            <AboutThisApp onClickDone={closeAboutApp} visible={aboutAppVisible} />
        </SettingsContainer>
    )
}

interface SettingsManagerState {
    backCLicked: boolean
    startOnLogin: boolean
    autoUpdate: boolean
    isLoaded: boolean
    aboutAppVisible: boolean
}

export default class SettingsManager extends React.Component<{}, SettingsManagerState> {
    private static onClickQuit() {
        ipc.callMain(QUIT_APPLICATION_CHANNEL)
    }

    constructor(props: {}) {
        super(props)

        this.state = {
            backCLicked: false,
            startOnLogin: false,
            autoUpdate: false,
            isLoaded: false,
            aboutAppVisible: false
        }

        this.onChangeStartOnLogin = this.onChangeStartOnLogin.bind(this)
        this.onChangeAutoUpdate = this.onChangeAutoUpdate.bind(this)
        this.onClickBack = this.onClickBack.bind(this)
    }

    async componentDidMount(): Promise<void> {
        const [startOnLogin, autoUpdate] = await Promise.all([
            ipc.callMain<void, boolean | undefined>(GET_START_ON_LOGIN),
            ipc.callMain<void, boolean>(GET_AUTO_UPDATE)
        ])
        this.setState({
            startOnLogin: startOnLogin ?? false,
            autoUpdate,
            isLoaded: true
        })
    }

    private async onChangeStartOnLogin(shouldStart: boolean) {
        this.setState({ startOnLogin: shouldStart })
        await ipc.callMain<boolean>(SET_START_ON_LOGIN, shouldStart)
    }

    private async onChangeAutoUpdate(autoUpdate: boolean) {
        this.setState({ autoUpdate })
        await ipc.callMain<boolean>(SET_AUTO_UPDATE, autoUpdate)
    }

    private onClickBack() {
        this.setState({ backCLicked: true })
    }

    render(): React.ReactNode {
        if (this.state.backCLicked) {
            return <Redirect to="/" />
        }
        if (!this.state.isLoaded) {
            return <div />
        }
        return (
            <Settings
                onClickBack={this.onClickBack}
                onClickStartOnLoginSwitch={this.onChangeStartOnLogin}
                onClickAutoUpdateSwitch={this.onChangeAutoUpdate}
                openAboutApp={() => this.setState({ aboutAppVisible: true })}
                closeAboutApp={() => this.setState({ aboutAppVisible: false })}
                shouldStartOnLogin={this.state.startOnLogin}
                autoUpdate={this.state.autoUpdate}
                onClickQuit={SettingsManager.onClickQuit}
                aboutAppVisible={this.state.aboutAppVisible}
            />
        )
    }
}