import {ReactElement, ReactEventHandler, useState} from "react";
import "../../styles/notificationConnector.css";
import Loader from "../Loader";
import NotificationConnectorFunctions from "../NotificationConnectorFunctions";
import {LunaseaItem} from "./records/ILunaseaRecord";
import {GotifyItem} from "./records/IGotifyRecord";
import {NtfyItem} from "./records/INtfyRecord";
import {PushoverItem} from "./records/IPushoverRecord";

export default interface INotificationConnector {
    name: string;
    url: string;
    headers: Record<string, string>[];
    httpMethod: string;
    body: string;
}

export function NotificationConnectorItem({apiUri, notificationConnector} : {apiUri: string, notificationConnector: INotificationConnector | null}) : ReactElement {
    if(notificationConnector != null)
        return <DefaultItem apiUri={apiUri} notificationConnector={notificationConnector} />

    const [selectedConnectorElement, setSelectedConnectorElement] = useState<ReactElement>(<DefaultItem apiUri={apiUri} notificationConnector={null} />);

    return <div>
        <div>New Notification Connector</div>
        <label>Type</label>
        <select defaultValue="default" onChange={(e) => {
            switch (e.currentTarget.value){
                case "default": setSelectedConnectorElement(<DefaultItem apiUri={apiUri} notificationConnector={null} />); break;
                case "gotify": setSelectedConnectorElement(<GotifyItem apiUri={apiUri} />); break;
                case "ntfy": setSelectedConnectorElement(<NtfyItem apiUri={apiUri} />); break;
                case "lunasea": setSelectedConnectorElement(<LunaseaItem apiUri={apiUri} />); break;
                case "pushover": setSelectedConnectorElement(<PushoverItem apiUri={apiUri} />); break;
            }
        }}>
            <option value="default">Generic REST</option>
            <option value="gotify">Gotify</option>
            <option value="ntfy">Ntfy</option>
            <option value="lunasea">Lunasea</option>
            <option value="pushover">Pushover</option>
        </select>
        {selectedConnectorElement}
    </div>;
}

function DefaultItem({apiUri, notificationConnector}:{apiUri: string, notificationConnector: INotificationConnector | null}) : ReactElement {
    const AddHeader : ReactEventHandler<HTMLButtonElement> = () => {
        let header : Record<string, string> = {};
        let x = info;
        x.headers = [header, ...x.headers];
        setInfo(x);
        setHeaderElements([...headerElements, <HeaderElement record={header} />])
    }
    const [headerElements, setHeaderElements] = useState<ReactElement[]>([]);
    const [info, setInfo] = useState<INotificationConnector>({
        name: "",
        url: "",
        headers: [],
        httpMethod: "",
        body: ""
    });
    const [loading, setLoading] = useState<boolean>(false);
    return <div className="NotificationConnectorItem">
        <input className="NotificationConnectorItem-Name" placeholder="Name" defaultValue={notificationConnector ? notificationConnector.name : ""}
               disabled={notificationConnector != null} onChange={(e) => setInfo({...info, name: e.currentTarget.value})} />
        <div className="NotificationConnectorItem-Url">
            <select className="NotificationConnectorItem-RequestMethod" defaultValue={notificationConnector ? notificationConnector.httpMethod : ""}
                    disabled={notificationConnector != null} onChange={(e)=> setInfo({...info, httpMethod: e.currentTarget.value})} >
                <option value="" disabled hidden>Request Method</option>
                <option value="GET">GET</option>
                <option value="POST">POST</option>
            </select>
            <input type="url" className="NotificationConnectorItem-RequestUrl" placeholder="URL" defaultValue={notificationConnector ? notificationConnector.url : ""}
                   disabled={notificationConnector != null} onChange={(e) => setInfo({...info, url: e.currentTarget.value})}  />
        </div>
        <textarea className="NotificationConnectorItem-Body" placeholder="Request-Body" defaultValue={notificationConnector ? notificationConnector.body : ""}
                  disabled={notificationConnector != null} onChange={(e)=> setInfo({...info, body: e.currentTarget.value})}  />
        {notificationConnector != null ? null :
            (
                <p className="NotificationConnectorItem-Explanation">Formatting placeholders: "%title" and "%text" can be placed in url, header-values and body and will be replaced when notifications are sent</p>
            )}
        <div className="NotificationConnectorItem-Headers">
            {headerElements}
            {notificationConnector
                ? notificationConnector.headers.map((h: Record<string, string>) =>
                    (<HeaderElement record={h} disabled={notificationConnector != null}/>)
                ) :
                (
                    <button className="NotificationConnectorItem-AddHeader" onClick={AddHeader}>Add Header</button>
                )
            }
        </div>
        <>
            <button className="NotificationConnectorItem-Save" onClick={(e) => {
                setLoading(true);
                NotificationConnectorFunctions.CreateNotificationConnector(apiUri, info)
                    .finally(() => setLoading(false));
            }}>Add</button>
            <Loader loading={loading} style={{width:"40px",height:"40px",margin:"25vh calc(sin(70)*(50% - 40px))"}}/>
        </>
    </div>
}

function HeaderElement({record, disabled} : {record: Record<string, string>, disabled?: boolean | null}) : ReactElement {
    return <div className="NotificationConnectorItem-Header" key={record.name}>
        <input type="text" className="NotificationConnectorItem-Header-Key" placeholder="Header-Key" defaultValue={record.name} disabled={disabled?disabled:false} onChange={(e) => record.name = e.currentTarget.value}/>
        <input type="text" className="NotificationConnectorItem-Header-Value" placeholder="Header-Value" defaultValue={record.value} disabled={disabled?disabled:false} onChange={(e) => record.value = e.currentTarget.value} />
    </div>;
}