import React, {FormEvent, useEffect, useState} from 'react';
import axios from 'axios';
import Modal from '@/components/ui/modal/Modal';
import {makeGetRequest, makePostRequest, makePutRequest} from '@/lib/request';
import {notify} from '@/lib/notify';
import RichTextTemplateEditor from './RichTextTemplateEditor';

type Props = {
    mode: 'manage' | 'generate' | null;
    token?: string;
    matters: any[];
    lawyers: any[];
    onClose: () => void;
    onGenerated: () => void;
};

const documentCategories = [
    ['agreement', 'Agreement'], ['affidavit', 'Affidavit'], ['application', 'Court application'],
    ['client_letter', 'Client letter'], ['contract', 'Contract'], ['correspondence', 'Correspondence'],
    ['court_order', 'Court order'], ['legal_opinion', 'Legal opinion'], ['memorandum', 'Memorandum'],
    ['notice', 'Notice'], ['petition', 'Petition'], ['pleading', 'Pleading'], ['policy', 'Policy'],
    ['report', 'Report'], ['written_submissions', 'Written submissions'], ['other', 'Other'],
] as const;

const emptyTemplate = {name: '', document_type: 'agreement', description: '', content: '', is_active: true};
const emptyGeneration = {template_id: '', client_matter_id: '', title: '', description: '', responsible_lawyer_id: '', confidentiality_classification: 'internal', allow_missing: false};

function documentCategoryLabel(value: string): string {
    return documentCategories.find(([key]) => key === value)?.[1] ?? value;
}

export default function DocumentTemplateModal({mode, token, matters, lawyers, onClose, onGenerated}: Props): JSX.Element {
    const [templates, setTemplates] = useState<any[]>([]);
    const [mergeFields, setMergeFields] = useState<string[]>([]);
    const [editing, setEditing] = useState<any | null>(null);
    const [form, setForm] = useState({...emptyTemplate});
    const [generation, setGeneration] = useState({...emptyGeneration});
    const [submitting, setSubmitting] = useState(false);

    useEffect(() => {
        if (!mode) return;
        Promise.all([
            makeGetRequest('/api/document-templates?include_inactive=1', {token}),
            makeGetRequest('/api/document-templates/merge-fields', {token}),
        ]).then(([templateResponse, fieldResponse]) => {
            setTemplates(templateResponse.data?.result ?? []);
            setMergeFields(fieldResponse.data?.result ?? []);
        }).catch((error: any) => notify.toastErrorMessage(error?.response?.data?.message || 'Unable to load document templates'));
    }, [mode, token]);

    function edit(template?: any) {
        setEditing(template ?? null);
        setForm(template ? {
            name: template.name,
            document_type: template.document_type,
            description: template.description ?? '',
            content: template.content,
            is_active: Boolean(template.is_active),
        } : {...emptyTemplate});
    }

    async function saveTemplate(event: FormEvent) {
        event.preventDefault();
        setSubmitting(true);
        try {
            if (editing) await makePutRequest(`/api/document-templates/${editing.id}`, form, {token});
            else await makePostRequest('/api/document-templates', form, {token});
            const response = await makeGetRequest('/api/document-templates?include_inactive=1', {token});
            setTemplates(response.data?.result ?? []);
            edit();
            notify.toastSuccessMessage(editing ? 'Template updated' : 'Template created');
        } catch (error: any) {
            const errors = error?.response?.data?.errors;
            notify.toastErrorMessage(errors ? Object.values(errors).flat().join(' ') : error?.response?.data?.message || 'Unable to save template');
        } finally { setSubmitting(false); }
    }

    async function deleteTemplate(template: any) {
        if (!confirm(`Delete template “${template.name}”?`)) return;
        try {
            await axios.delete(`/api/document-templates/${template.id}`, {headers: token ? {Authorization: `Bearer ${token}`} : {}});
            setTemplates(current => current.filter(item => item.id !== template.id));
            notify.toastSuccessMessage('Template deleted');
        } catch (error: any) {
            notify.toastErrorMessage(error?.response?.data?.message || 'Unable to delete template');
        }
    }

    async function generate(event: FormEvent) {
        event.preventDefault();
        setSubmitting(true);
        try {
            await makePostRequest(`/api/document-templates/${generation.template_id}/generate`, {
                ...generation,
                client_matter_id: Number(generation.client_matter_id),
                responsible_lawyer_id: generation.responsible_lawyer_id ? Number(generation.responsible_lawyer_id) : null,
            }, {token});
            notify.toastSuccessMessage('Document generated from template');
            setGeneration({...emptyGeneration});
            onGenerated();
            onClose();
        } catch (error: any) {
            const errors = error?.response?.data?.errors;
            notify.toastErrorMessage(errors ? Object.values(errors).flat().join(' ') : error?.response?.data?.message || 'Unable to generate document');
        } finally { setSubmitting(false); }
    }

    const selectedMatter = matters.find(matter => matter.id === Number(generation.client_matter_id));

    if (mode === 'generate') return <Modal open onClose={onClose} title="Generate document from template" maxWidthClassName="max-w-xl" footer={<><button type="button" className="ti-btn ti-btn-light" onClick={onClose}>Cancel</button><button type="submit" form="generate-document-form" className="ti-btn ti-btn-primary" disabled={submitting}>{submitting ? 'Generating…' : 'Generate document'}</button></>}>
        <form id="generate-document-form" className="space-y-4" onSubmit={generate}>
            <Field label="Template"><select className="ti-form-input" required value={generation.template_id} onChange={event => setGeneration({...generation, template_id: event.target.value})}><option value="">Select template</option>{templates.filter(item => item.is_active).map(item => <option key={item.id} value={item.id}>{item.name} · {documentCategoryLabel(item.document_type)}</option>)}</select></Field>
            <Field label="Matter"><select className="ti-form-input" required value={generation.client_matter_id} onChange={event => setGeneration({...generation, client_matter_id: event.target.value, responsible_lawyer_id: matters.find(item => item.id === Number(event.target.value))?.attorney_id?.toString() ?? ''})}><option value="">Select matter</option>{matters.map(item => <option key={item.id} value={item.id}>{item.reference_number} — {item.client?.name}</option>)}</select></Field>
            {selectedMatter?.litigation_case ? <p className="rounded bg-indigo-50 p-2 text-sm text-indigo-700">Linked to litigation {selectedMatter.litigation_case.case_number}.</p> : null}
            <Field label="Document title"><input className="ti-form-input" required value={generation.title} onChange={event => setGeneration({...generation, title: event.target.value})} /></Field>
            <Field label="Responsible lawyer"><select className="ti-form-input" value={generation.responsible_lawyer_id} onChange={event => setGeneration({...generation, responsible_lawyer_id: event.target.value})}><option value="">Matter lead lawyer</option>{lawyers.map(item => <option key={item.id} value={item.id}>{item.name}</option>)}</select></Field>
            <Field label="Confidentiality"><select className="ti-form-input" value={generation.confidentiality_classification} onChange={event => setGeneration({...generation, confidentiality_classification: event.target.value})}><option value="public">Public</option><option value="internal">Internal</option><option value="confidential">Confidential</option><option value="restricted">Restricted</option></select></Field>
            <Field label="Description"><textarea className="ti-form-input" rows={2} value={generation.description} onChange={event => setGeneration({...generation, description: event.target.value})} /></Field>
            <label className="flex items-center gap-2 text-sm"><input type="checkbox" checked={generation.allow_missing} onChange={event => setGeneration({...generation, allow_missing: event.target.checked})} />Generate even when optional system values are missing</label>
        </form>
    </Modal>;

    return <Modal open={mode === 'manage'} onClose={onClose} title="Document templates and merge fields" maxWidthClassName="max-w-5xl" bodyClassName="max-h-[76vh] overflow-y-auto" footer={<button type="button" className="ti-btn ti-btn-light" onClick={onClose}>Close</button>}>
        <div className="grid gap-6 lg:grid-cols-2">
            <div><div className="mb-3 flex items-center justify-between"><h5 className="font-semibold">Templates</h5><button type="button" className="ti-btn ti-btn-sm ti-btn-primary" onClick={() => edit()}><i className="fa fa-plus me-2" />New template</button></div><div className="space-y-2">{templates.length ? templates.map(template => <div key={template.id} className="flex items-center justify-between rounded-lg border p-3"><div><div className="font-medium">{template.name}</div><div className="text-xs text-gray-500">{documentCategoryLabel(template.document_type)} · {template.is_active ? 'Active' : 'Inactive'}</div></div><div className="flex gap-1"><button type="button" className="h-8 w-8 rounded-full p-0 ti-btn ti-btn-soft-primary" onClick={() => edit(template)} title="Edit template"><i className="fa fa-pencil" /></button><button type="button" className="h-8 w-8 rounded-full p-0 ti-btn ti-btn-soft-danger" onClick={() => deleteTemplate(template)} title="Delete template"><i className="fa fa-trash" /></button></div></div>) : <p className="text-sm text-gray-500">No templates have been configured.</p>}</div>
                <div className="mt-5 rounded-lg bg-gray-50 p-3"><div className="mb-2 text-sm font-semibold">Supported merge fields</div><div className="flex flex-wrap gap-1">{mergeFields.map(field => <code key={field} className="rounded bg-white px-2 py-1 text-xs">{'{{'}{field}{'}}'}</code>)}</div></div>
            </div>
            <form className="space-y-4 rounded-lg border p-4" onSubmit={saveTemplate}><h5 className="font-semibold">{editing ? `Edit ${editing.name}` : 'New template'}</h5><Field label="Template name"><input className="ti-form-input" required value={form.name} onChange={event => setForm({...form, name: event.target.value})} /></Field><Field label="Document category"><select className="ti-form-input" required value={form.document_type} onChange={event => setForm({...form, document_type: event.target.value})}>{!documentCategories.some(([value]) => value === form.document_type) && form.document_type ? <option value={form.document_type}>{form.document_type} (existing)</option> : null}{documentCategories.map(([value, title]) => <option key={value} value={value}>{title}</option>)}</select><span className="mt-1 block text-xs text-gray-500">This classifies the document; generated template files are PDF.</span></Field><Field label="Description"><textarea className="ti-form-input" rows={2} value={form.description} onChange={event => setForm({...form, description: event.target.value})} /></Field><div><span className="ti-form-label">Template content</span><RichTextTemplateEditor value={form.content} mergeFields={mergeFields} onChange={content => setForm(current => ({...current, content}))} /></div><label className="flex items-center gap-2 text-sm"><input type="checkbox" checked={form.is_active} onChange={event => setForm({...form, is_active: event.target.checked})} />Available for document generation</label><div className="flex justify-end gap-2"><button type="button" className="ti-btn ti-btn-light" onClick={() => edit()}>Reset</button><button type="submit" className="ti-btn ti-btn-primary" disabled={submitting}>{submitting ? 'Saving…' : 'Save template'}</button></div></form>
        </div>
    </Modal>;
}

function Field({label, children}: {label: string; children: React.ReactNode}): JSX.Element {
    return <label className="block"><span className="ti-form-label">{label}</span>{children}</label>;
}
