import React, { useState } from 'react';
import { api } from '../../lib/api';
import { useForm, useList, useSubmit } from '../../lib/hooks';
import { errorMessage, t } from '../../lib/i18n';
import { ActionButton, Actions, Alert, Button, Field, FilterBar, FormModal, IconButton, ListView, PageHeader, Row, RowLegend } from '../../components/ui';

const LOGIN_STATUSES = ['invited', 'active', 'inactive'];

/** The people from the landlord's insurer who review rental applications. */
export default function InsuranceAgentsPage() {
    const list = useList('/api/admin/insurance-agents', { q: '', includeInactive: '' });
    const [editing, setEditing] = useState(null);
    const [busyId, setBusyId] = useState(null);
    const [error, setError] = useState(null);
    const [notice, setNotice] = useState(null);

    const act = async (agent, action, successMessage) => {
        setBusyId(agent.id);
        setError(null);
        setNotice(null);
        try {
            await action();
            if (successMessage) setNotice(successMessage);
            list.reload();
        } catch (err) {
            setError(errorMessage(err));
        } finally {
            setBusyId(null);
        }
    };

    const toggleActive = (agent) => {
        if (agent.active && !window.confirm(t('insuranceAgents.confirmDisable', { name: agent.fullName }))) return;
        act(agent, () =>
            agent.active ? api.del(`/api/admin/insurance-agents/${agent.id}`) : api.patch(`/api/admin/insurance-agents/${agent.id}`, { active: true }),
        );
    };

    return (
        <>
            <PageHeader
                title={t('nav.insuranceAgents')}
                subtitle={t('insuranceAgents.subtitle')}
                actions={<Button onClick={() => setEditing({})}>{t('insuranceAgents.new')}</Button>}
            />
            <FilterBar
                search={list.filters.q}
                onSearch={(q) => list.update({ q })}
                searchPlaceholder={t('insuranceAgents.searchPlaceholder')}
                filters={[
                    {
                        name: 'status',
                        label: t('common.status'),
                        value: list.filters.includeInactive === '1' ? 'all' : 'active',
                        onChange: (value) => list.update({ includeInactive: value === 'all' ? '1' : '' }),
                        options: [
                            { value: 'active', label: t('common.onlyActive') },
                            { value: 'all', label: t('common.all') },
                        ],
                    },
                ]}
            />
            <Alert kind="success" onDismiss={() => setNotice(null)}>{notice}</Alert>
            <Alert kind="error" onDismiss={() => setError(null)}>{error}</Alert>
            <RowLegend
                statuses={LOGIN_STATUSES.map((status) => ({ value: status, label: status === 'inactive' ? t('common.inactive') : t(`login.status.${status}`) }))}
            />

            <ListView
                list={list}
                empty={t('insuranceAgents.empty')}
                columns={[t('tenants.fullName'), t('insuranceAgents.email')]}
                renderRow={(agent) => (
                    // Like renters, an agent's state is whether they can sign in; a disabled agent is greyed out.
                    <Row
                        key={agent.id}
                        status={agent.active ? agent.status : 'inactive'}
                        label={agent.active ? t(`login.status.${agent.status}`) : t('common.inactive')}
                        muted={!agent.active}
                    >
                        <td className="strong">{agent.fullName}</td>
                        <td>{agent.email}</td>
                        <Actions>
                            {agent.active && agent.status === 'invited' && (
                                <ActionButton
                                    action="setup"
                                    busy={busyId === agent.id}
                                    onClick={() =>
                                        act(agent, () => api.post(`/api/admin/insurance-agents/${agent.id}/invitation`), t('tenants.invitationSent', { email: agent.email }))
                                    }
                                >
                                    {t('tenants.resendInvitation')}
                                </ActionButton>
                            )}
                            <IconButton icon="pencil" label={t('common.edit')} onClick={() => setEditing(agent)} />
                            <IconButton icon={agent.active ? 'ban' : 'check'} label={agent.active ? t('common.disable') : t('common.enable')} onClick={() => toggleActive(agent)} />
                        </Actions>
                    </Row>
                )}
            />

            {editing && (
                <AgentForm
                    agent={editing}
                    onClose={() => setEditing(null)}
                    onSaved={(created) => {
                        setEditing(null);
                        if (created) setNotice(t('tenants.invitationSent', { email: created.email }));
                        list.reload();
                    }}
                />
            )}
        </>
    );
}

function AgentForm({ agent, onClose, onSaved }) {
    const isNew = !agent.id;
    const form = useForm({ fullName: agent.fullName || '', email: agent.email || '' });
    const submit = useSubmit();
    const { errors } = submit;

    const save = async () => {
        const result = await submit.run(() =>
            isNew
                ? api.post('/api/admin/insurance-agents', { fullName: form.values.fullName, email: form.values.email })
                : api.patch(`/api/admin/insurance-agents/${agent.id}`, { fullName: form.values.fullName }),
        );
        if (result.ok) onSaved(isNew ? result.value : null);
    };

    return (
        <FormModal
            title={isNew ? t('insuranceAgents.new') : t('insuranceAgents.edit')}
            onClose={onClose}
            onSubmit={save}
            submit={submit}
            submitLabel={isNew ? t('insuranceAgents.invite') : undefined}
        >
            <Field label={t('tenants.fullName')} error={errors.fullName}>
                <input {...form.bind('fullName')} autoFocus />
            </Field>
            <Field label={t('insuranceAgents.email')} error={errors.email} hint={isNew ? t('insuranceAgents.emailHint') : undefined}>
                <input type="email" {...form.bind('email')} readOnly={!isNew} />
            </Field>
        </FormModal>
    );
}
