import React from "react";
import { useEffect, useState } from "react";
import { Link, useParams, useLocation } from "react-router-dom";
import "./Index.css";
import { policy, needConsent } from "./ManageServiceProvider";
import format from "date-fns/format";

const hasConsent = (patient, service) => {
    let consent = patient.Consent.filter(x => x.ServiceID == service.ServiceID)[0]

    if (!consent) {
        return false
    }

    consent.ConsentGivenOn = format(new Date(consent.ConsentGivenOn), "yyyy-MM-dd")
    return consent
}

const ConsentLink = ({patient, service, setConsentId}) => {
    const consent = hasConsent(patient, service)

    return (
        <span>
            (<a href="#" onClick={e => {
                e.stopPropagation()
                e.preventDefault()
                setConsentId([patient, service])
            }}>{ consent ? `toestemming gegeven op: ${format(new Date(consent.ConsentGivenOn), 'dd/MM/yyyy')}` : "toestemming vereist"}</a>)
        </span>
    )
}

const DropDown = ({patient, services, updateSubscription, loading, saveConsent, removeConsent}) => {
    const [open, _setOpen] = useState(false)
    const [consentId, setConsentId] = useState(false)
    const close = () => {
        _setOpen(false)
        window.removeEventListener('click', close)
    }

    const setOpen = (x) => {
        _setOpen(x)
        window.addEventListener('click', close)
    }

    const isSubscribed = (patient, service) => {
        const present = service.Subscriptions.map(x => x.ID).indexOf(patient.ID) != -1

        return policy(service) == 'opt-out' ? !present : present
    }

    const applyPolicy = (checked, service) => {
        return policy(service) == 'opt-out' ? !checked : checked
    }

    const systems = services.reduce((acc, cur) => {
        if (!acc[cur.ServiceProvider.System]) {
            acc[cur.ServiceProvider.System] = []
        }

        acc[cur.ServiceProvider.System].push(cur)
        return acc
    }, {})

    return (
        <div className={["c-dropdown", open ? "c-dropdown--open" : null].filter(Boolean).join(' ')}>
            <a
                className="c-button c-button--sm"
                onClick={e => e.preventDefault() || e.stopPropagation() || setOpen(true)}
            >
                Aanmelden
            </a>
            <div
                className="c-dropdown__options"
                onClick={e => e.stopPropagation()}
            >
                {Object.keys(systems).map(sys => {
                    return (
                        <div className="c-dropdown__system" key={sys}>
                            {consentId ? <ConsentModal
                                close={_ => setConsentId(false)}
                                loading={loading}
                                service={consentId ? consentId[1] : null}
                                patient={consentId ? consentId[0] : null}
                                saveConsent={saveConsent}
                                removeConsent={removeConsent}
                            /> : null}
                            <span className="c-dropdown__system-option">{sys}</span>
                            <div className="c-dropdown__ul">
                                {
                                    systems[sys].map( x => {
                                        return  (
                                            <div className="c-dropdown__option" key={x.ID}>
                                                <label className="c-dropdown__label">
                                                    <span><input
                                                        type="checkbox"
                                                        checked={isSubscribed(patient, x)}
                                                        disabled={loading}
                                                        readOnly={loading}
                                                        onChange={(e) => {
                                                            e.stopPropagation()
                                                            const enable = applyPolicy(e.target.checked, x)
                                                            updateSubscription(patient, x, enable)
                                                            enable && needConsent(x) && setConsentId([patient, x])
                                                        }} name="" id=""
                                                    /> {x.Name} {needConsent(x) ? <ConsentLink saveConsent={saveConsent} setConsentId={setConsentId} patient={patient} service={x}/> : null}</span>
                                                </label>
                                            </div>
                                        )
                                    })
                                }
                            </div>
                        </div>
                    )
                })}
            </div>
        </div>
    )
}

export const ConsentModal = ({loading, close, service, patient, saveConsent, removeConsent}) => {

    const [consent, setConsent] = useState(
        hasConsent(patient, service)
        ? Object.assign({}, hasConsent(patient, service), {PatientID: patient.ID, EnableBrochure: !!hasConsent(patient, service).Brochure,})
        : {
            PatientID: patient.ID,
            ServiceID: service.ServiceID,
            ConsentGivenOn: format(new Date(), "yyyy-dd-MM"),
            VerbalConsent: false,
            EnableBrochure: false,
            Brochure: "",
            Brochureversion: "",
        }
    )

    return (
        <div className="c-modal-overlay" onClick={e => e.stopPropagation()}>
            <div className="c-modal">
                <a onClick={close} className="c-modal__close">x</a>
                <div className="c-form-row">
                    <label htmlFor="">Toestemming gegeven op</label>
                    <input className="c-input" onChange={x => setConsent(Object.assign({}, consent, {ConsentGivenOn: x.target.value}))} value={consent.ConsentGivenOn} type="date"/>
                </div>
                <div className="c-form-row" style={{display: "flex"}}>
                    <input style={{marginRight: 5}} checked={consent.VerbalConsent} onChange={x => {
                        x.stopPropagation()
                        setConsent(Object.assign({}, consent, {VerbalConsent: x.target.checked}))
                    }} type="checkbox"/>
                    <label htmlFor="">Mondeling geïnformeerd</label>
                </div>
                <div className="c-form-row" style={{display: "flex"}}>
                    <input style={{marginRight: 5}} checked={consent.EnableBrochure} onChange={x => {
                        x.stopPropagation()
                        setConsent(Object.assign({}, consent, {EnableBrochure: x.target.checked}))
                    }} type="checkbox"/>
                    <label htmlFor="">Geïnformeerd d.m.v. brochure</label>
                </div>
                <div className="c-form-row">
                    <label htmlFor="" style={{opacity: consent.EnableBrochure ? 1 : 0.3}}>Brochure</label>
                    <input className="c-input" disabled={!consent.EnableBrochure} onChange={x => setConsent(Object.assign({}, consent, {Brochure: x.target.value}))} value={consent.Brochure} type="text"/>
                </div>
                <div className="c-form-row">
                    <label htmlFor="" style={{opacity: consent.EnableBrochure ? 1 : 0.3}}>Brochure versie</label>
                    <input className="c-input" disabled={!consent.EnableBrochure} onChange={x => setConsent(Object.assign({}, consent, {Brochureversion: x.target.value}))} value={consent.Brochureversion} type="text"/>
                </div>
                <div className="c-modal-buttons">
                    <button className="c-button c-button--default" disabled={loading}  onClick={async x => {
                        await removeConsent(Object.assign({}, consent))
                        close()
                    }}>Toestemming intrekken</button>
                    <button className="c-button" disabled={loading} onClick={async x => {
                        await saveConsent(Object.assign({}, consent))
                        close()
                    }}>Opslaan</button>
                </div>
            </div>
        </div>
    )
}

const Patients = () => {
    const location = useLocation()
    const [loading, setLoading] = useState(false)
    const [patients, setPatients] = useState([])
    const [services, setServices] = useState([])

    const updateServices = async () => fetch(`/api/services`).then(x => x.json()).then(x => setServices(x))
    const updatePatients = async () => fetch(`/api/patients`).then(x => x.json()).then(x => setPatients(x))

    useEffect(() => {
        updatePatients()
    }, [location])

    useEffect(() => {
        updateServices()
    }, [location])

    const updateSubscription = async (patient, service, active) => {
        setLoading(true)
        await fetch(`/api/services/${service.ID}/subscriptions`, {
            method: "POST",
            headers: {
            'Content-Type': 'application/json'
            },
            body: JSON.stringify({active: active, patient: patient.ID})
        })

        await updateServices()

        setLoading(false)
    }

    const saveConsent = async (consent) => {
        setLoading(true)

        consent.ConsentGivenOn = new Date(consent.ConsentGivenOn)
        if (!consent.EnableBrochure) {
            consent.Brochure = ""
            consent.Brochureversion = ""
        }

        await fetch(`/api/patients/${consent.PatientID}/consent`, {
            method: "POST",
            headers: {
            'Content-Type': 'application/json'
            },
            body: JSON.stringify(consent)
        })

        await updatePatients()

        setLoading(false)
    }

    const removeConsent = async (consent) => {
        setLoading(true)

        if (consent.ID) {
            await fetch(`/api/patients/${consent.PatientID}/consent/${consent.ID}`, {
                method: "DELETE"
            })
        }


        await updatePatients()

        setLoading(false)
    }

    return (
        <div>
            <h1 className="t-page-header">Patienten</h1>
            <table className="c-table" style={{width: "initial"}}>
                <thead>
                    <tr>
                        <th style={{width: 200}}>Naam</th>
                        <th style={{width: 200}}>Geboortedatum</th>
                        <th style={{width: 200}}>BSN</th>
                        <th>Acties</th>
                    </tr>
                </thead>
                <tbody>
                {patients.map(x => {
                    return (<tr key={x.ID}>

                        <td>{x.Name}</td>
                        <td>{x.Birthdate}</td>
                        <td>{x.ExternalId}</td>
                        <td>
                            {services.length ? <DropDown
                                updateSubscription={updateSubscription}
                                patient={x}
                                services={services}
                                loading={loading}
                                saveConsent={saveConsent}
                                removeConsent={removeConsent}
                            /> : null}
                        </td>
                    </tr>)
                })}
                </tbody>
            </table>
        </div>
    );
};

export default Patients;