import { QrPreviewImage } from '@admin/components/qr/qr-preview-image';
import { adminToast } from '@admin/components/ui/admin-toast';
import { CreatePageLayout } from '@admin/components/ui/create-page-layout';
import { DataTable, type DataTableColumn } from '@admin/components/ui/data-table';
import { DeleteConfirmationModal } from '@admin/components/ui/delete-confirmation-modal';
import { formClassName, formHelpClassName } from '@admin/components/ui/field-styles';
import { FormGroup } from '@admin/components/ui/forms/form-group';
import { FormSwitch } from '@admin/components/ui/forms/form-switch';
import { useCrudPermissions } from '@admin/hooks/use-crud-permissions';
import { useFormResponse } from '@admin/hooks/use-form-response';
import { dashboardPersistentLayout } from '@admin/layouts/dashboard-page-layout';
import { buildQrUrl } from '@admin/lib/qr-code';
import { cn } from '@admin/lib/utils';
import EditQrCode from '@admin/pages/qr-codes/edit-qr-code';
import type { QrCodeDefaults } from '@admin/types/qr-code';
import { Head, useForm } from '@inertiajs/react';
import { FormEvent, useEffect, useState } from 'react';

type QrCodeSummary = {
    id: number;
    name: string;
    status: boolean;
};

type CreateQrCodeProps = {
    qrCodes: QrCodeSummary[];
    defaults: QrCodeDefaults;
};

const sidebarColumns: DataTableColumn<QrCodeSummary>[] = [
    { header: 'Name', key: 'name', truncate: true, className: 'w-[50%]' },
    { header: 'Status', key: 'status', className: 'w-24' },
];

function CreateQrCode({ qrCodes, defaults }: CreateQrCodeProps) {
    const { canEdit, canDelete } = useCrudPermissions('qr-code');
    const [isEditModalOpen, setIsEditModalOpen] = useState(false);
    const [initialData, setInitialData] = useState<Record<string, unknown> | null>(null);
    const [deleteModal, setDeleteModal] = useState<{ show: boolean; qrCode: QrCodeSummary | null }>({
        show: false,
        qrCode: null,
    });
    const [previewUrl, setPreviewUrl] = useState('');
    const { data, setData, post, processing, errors, reset } = useForm({
        name: '',
        url: '',
        status: true,
    });
    const action = useFormResponse({ onComplete: reset, loadingMessage: 'Creating QR code...' });

    useEffect(() => {
        if (!data.url.startsWith('http')) {
            setPreviewUrl('');

            return;
        }

        const timeoutId = window.setTimeout(() => {
            setPreviewUrl(
                buildQrUrl(route('admin.qr-codes.preview', { format: 'png' }), {
                    size: defaults.preview_size,
                    template: defaults.template,
                    color: defaults.color,
                    background: defaults.background,
                    logo: false,
                    logoWidth: defaults.logo_width,
                    punchout: false,
                    extra: {
                        type: 'url',
                        'payload[url]': data.url,
                    },
                }),
            );
        }, 400);

        return () => window.clearTimeout(timeoutId);
    }, [data.url, defaults]);

    const handleEdit = async (row: QrCodeSummary) => {
        try {
            const response = await fetch(`/admin/edit_qr_code/${row.id}`);
            if (!response.ok) {
                throw new Error('Failed to fetch QR code');
            }

            setInitialData((await response.json()) as Record<string, unknown>);
            setIsEditModalOpen(true);
        } catch {
            adminToast.error('Could not load QR code details');
        }
    };

    const handleSubmit = (event: FormEvent) => {
        event.preventDefault();
        post('/admin/api/create_qr_code', {
            onStart: action.onStart,
            onSuccess: action.onSuccess,
            onError: action.onError,
            preserveScroll: true,
        });
    };

    return (
        <>
            <Head title="Create QR code" />

            <CreatePageLayout
                indexHref={route('admin.qr-codes')}
                form={
                    <div className="box">
                        <div className="box-header">
                            <h5 className="box-title">Add QR code</h5>
                        </div>
                        <div className="box-body">
                            <form className={formClassName} noValidate onSubmit={handleSubmit}>
                                <FormGroup
                                    label="Name"
                                    error={errors.name}
                                    helpText="A label for this code, such as Wi-Fi card or front desk."
                                    inputProps={{
                                        value: data.name,
                                        onChange: (event) => setData('name', event.target.value),
                                        required: true,
                                    }}
                                />
                                <FormGroup
                                    label="URL"
                                    error={errors.url ?? errors['payload.url']}
                                    helpText="The code opens this address when it is scanned."
                                    inputProps={{
                                        type: 'url',
                                        value: data.url,
                                        placeholder: 'https://',
                                        onChange: (event) => setData('url', event.target.value),
                                        required: true,
                                    }}
                                />
                                <FormSwitch
                                    label="Active"
                                    checked={data.status}
                                    onChange={(event) => setData('status', event.target.checked)}
                                />
                                <div className="mb-4">
                                    <p className={cn('mb-2', formHelpClassName)}>The code appears as soon as the URL is valid.</p>
                                    <QrPreviewImage src={previewUrl || undefined} alt="QR preview" size={defaults.preview_size} />
                                </div>
                                <button type="submit" className="ti-btn ti-btn-primary" disabled={processing}>
                                    Save
                                </button>
                            </form>
                        </div>
                    </div>
                }
                sidebar={
                    <DataTable
                        data={qrCodes}
                        columns={sidebarColumns}
                        title="QR codes"
                        compact
                        onEdit={canEdit ? handleEdit : undefined}
                        onDelete={canDelete ? (row) => setDeleteModal({ show: true, qrCode: row }) : undefined}
                        showEdit={canEdit}
                        showDelete={canDelete}
                        noDataText="No QR codes yet"
                    />
                }
            />

            <DeleteConfirmationModal
                isOpen={deleteModal.show}
                onClose={() => setDeleteModal({ show: false, qrCode: null })}
                itemName={deleteModal.qrCode?.name ?? 'this QR code'}
                itemType="QR code"
                deleteEndpoint={`/admin/api/delete_qr_code/${deleteModal.qrCode?.id ?? ''}`}
                loadingMessage="Deleting QR code..."
            />

            <EditQrCode isOpen={isEditModalOpen} onClose={() => setIsEditModalOpen(false)} initialData={initialData} />
        </>
    );
}

export default Object.assign(CreateQrCode, {
    layout: dashboardPersistentLayout('Create QR code', 'Add a link and generate its code'),
});
