import { useEffect, useRef, useState } from 'react';

function cx(...parts: Array<string | false | null | undefined>) {
    return parts.filter(Boolean).join(' ');
}

export function StatusBadge({ status }) {
    const statusColors = {
        Healthy: 'mono-status-ok',
        Running: 'mono-status-ok',
        Deploying: 'mono-status-warn',
        Pending: 'mono-status-warn',
        Building: 'mono-status-warn',
        Pushing: 'mono-status-warn',
        Pushed: 'mono-status-warn',
        Unhealthy: 'mono-status-bad',
        Failed: 'mono-status-bad',
        Stopped: 'mono-status-muted',
        Cancelled: 'mono-status-muted',
        Superseded: 'mono-status-muted',
        Expired: 'mono-status-muted',
        Terminating: 'mono-status-muted',
    };

    const color = statusColors[status] || 'mono-status-muted';

    return <span className={`mono-status ${color}`}>{status}</span>;
}

export function Button({
    children,
    onClick,
    variant = 'primary',
    size = 'md',
    loading = false,
    disabled = false,
    type = 'button',
    className = '',
}) {
    const baseClasses = 'mono-btn';
    const variantClasses = {
        primary: 'mono-btn-primary',
        secondary: 'mono-btn-secondary',
        danger: 'mono-btn-danger',
    };
    const sizeClasses = {
        sm: 'mono-btn-sm',
        md: 'mono-btn-md',
        lg: 'mono-btn-lg',
    };

    return (
        <button
            type={type as 'button' | 'submit' | 'reset'}
            onClick={onClick}
            disabled={disabled || loading}
            className={`${baseClasses} ${variantClasses[variant]} ${sizeClasses[size]} ${className}`}
        >
            {loading && <div className="mono-spinner" />}
            {children}
        </button>
    );
}

export function Modal({
    isOpen,
    onClose,
    title,
    children,
    maxWidth = 'max-w-2xl',
    modalClassName = '',
    bodyClassName = '',
}) {
    const [bodyElement, setBodyElement] = useState<HTMLDivElement | null>(null);

    useEffect(() => {
        const handleEscape = (e) => {
            if (e.key === 'Escape' && isOpen) {
                onClose();
            }
        };
        const handleNavigate = () => {
            if (isOpen) onClose();
        };
        const handleCloseAll = () => {
            if (isOpen) onClose();
        };

        document.addEventListener('keydown', handleEscape);
        window.addEventListener('rise:navigate', handleNavigate as EventListener);
        window.addEventListener('rise:close-modals', handleCloseAll as EventListener);
        return () => {
            document.removeEventListener('keydown', handleEscape);
            window.removeEventListener('rise:navigate', handleNavigate as EventListener);
            window.removeEventListener('rise:close-modals', handleCloseAll as EventListener);
        };
    }, [isOpen, onClose]);

    useEffect(() => {
        if (isOpen) {
            document.body.style.overflow = 'hidden';
        } else {
            document.body.style.overflow = 'unset';
        }
        return () => {
            document.body.style.overflow = 'unset';
        };
    }, [isOpen]);

    useEffect(() => {
        if (!isOpen || !bodyElement) return;

        const timer = window.setTimeout(() => {
            const firstInput = bodyElement.querySelector<HTMLElement>(
                '[data-autofocus], input:not([type="hidden"]):not([disabled]), select:not([disabled]), textarea:not([disabled])'
            );
            firstInput?.focus();
        }, 0);

        return () => window.clearTimeout(timer);
    }, [isOpen, bodyElement]);

    if (!isOpen) return null;

    return (
        <div className="modal-backdrop" onClick={onClose}>
            <div className={cx('modal-content mono-modal-shell', maxWidth, modalClassName)} onClick={(e) => e.stopPropagation()}>
                <div className="modal-header mono-modal-header">
                    <h3 className="modal-title">{title}</h3>
                    <button onClick={onClose} className="modal-close-button" aria-label="Close modal">
                        <div
                            className="w-6 h-6 svg-mask"
                            style={{
                                maskImage: 'url(/assets/close-x.svg)',
                                WebkitMaskImage: 'url(/assets/close-x.svg)',
                            }}
                        ></div>
                    </button>
                </div>
                <div className={cx('modal-body mono-modal-body', bodyClassName)} ref={setBodyElement}>{children}</div>
            </div>
        </div>
    );
}

export function ModalSection({ children, className = '' }) {
    return <div className={cx('mono-modal-section', className)}>{children}</div>;
}

export function ModalActions({ children, className = '' }) {
    return <div className={cx('mono-modal-actions', className)}>{children}</div>;
}

export function ModalTabs({ children, className = '' }) {
    return <div className={cx('mono-modal-tabs', className)}>{children}</div>;
}

export function MonoTabButton({
    children,
    active = false,
    tone = 'default',
    onClick,
    className = '',
}) {
    return (
        <button
            type="button"
            onClick={onClick}
            className={cx('mono-tab-trigger', active && 'active', tone === 'danger' && 'mono-tab-trigger-danger', className)}
        >
            {children}
        </button>
    );
}

export function MonoStatusPill({ tone = 'muted', uppercase = true, className = '', children }) {
    const toneClass = {
        ok: 'mono-pill-ok',
        warn: 'mono-pill-warn',
        bad: 'mono-pill-bad',
        muted: 'mono-pill-muted',
    }[tone] || 'mono-pill-muted';

    return <span className={cx('mono-status-pill', toneClass, uppercase && 'mono-status-pill-up', className)}>{children}</span>;
}

export function MonoNotice({ tone = 'info', title = '', className = '', children }) {
    const toneClass = {
        info: 'mono-notice-info',
        warn: 'mono-notice-warn',
        error: 'mono-notice-error',
        success: 'mono-notice-success',
        muted: 'mono-notice-muted',
    }[tone] || 'mono-notice-info';

    return (
        <div className={cx('mono-notice', toneClass, className)}>
            {title && <h4 className="mono-notice-title">{title}</h4>}
            <div className="mono-notice-body">{children}</div>
        </div>
    );
}

export function MonoCodeBlock({ as = 'pre', className = '', children }) {
    const Tag = as as any;
    return (
        <Tag className={cx('mono-code-block', className)}>
            {children}
        </Tag>
    );
}

export function SegmentedRadioGroup({
    label,
    name,
    value,
    onChange,
    options = [],
    ariaLabel,
    className = '',
}) {
    return (
        <div className={cx('form-field', className)}>
            {label && <p className="mono-label">{label}</p>}
            <div className="mono-segmented mt-1" role="radiogroup" aria-label={ariaLabel || label || name}>
                {options.map((option) => (
                    <label key={option.value} className={`mono-segmented-option ${value === option.value ? 'active' : ''}`}>
                        <input
                            type="radio"
                            name={name}
                            value={option.value}
                            checked={value === option.value}
                            onChange={() => onChange(option.value)}
                            className="mono-segmented-input"
                        />
                        <span>{option.label}</span>
                    </label>
                ))}
            </div>
        </div>
    );
}

export function FormField({
    label,
    id,
    type = 'text',
    value,
    onChange,
    error,
    required = false,
    placeholder,
    disabled = false,
    options = [],
    rows = 3,
    list = undefined,
    children = null,
}) {
    const inputClasses = `mono-input ${error ? 'mono-input-error' : ''}`;

    return (
        <div className="form-field">
            <label htmlFor={id} className="mono-label">
                {label}
                {required && <span className="text-red-300 ml-1">*</span>}
            </label>

            {type === 'select' ? (
                <select id={id} value={value} onChange={onChange} disabled={disabled} className={inputClasses}>
                    {children
                        ? children
                        : options.map((opt) => (
                              <option key={opt.value} value={opt.value}>
                                  {opt.label}
                              </option>
                          ))}
                </select>
            ) : type === 'textarea' ? (
                <textarea
                    id={id}
                    value={value}
                    onChange={onChange}
                    placeholder={placeholder}
                    disabled={disabled}
                    rows={rows}
                    className={inputClasses}
                />
            ) : type === 'checkbox' ? (
                <div className="flex items-center">
                    <input type="checkbox" id={id} checked={value} onChange={onChange} disabled={disabled} className="mono-checkbox" />
                    <label htmlFor={id} className="ml-2 text-sm text-gray-300">
                        {placeholder}
                    </label>
                </div>
            ) : (
                <input
                    type={type}
                    id={id}
                    value={value}
                    onChange={onChange}
                    placeholder={placeholder}
                    disabled={disabled}
                    list={list}
                    className={inputClasses}
                />
            )}

            {error && <p className="mt-2 text-sm text-red-300">{error}</p>}
        </div>
    );
}

export function AutocompleteInput({
    id,
    value,
    onChange,
    options = [],
    type = 'text',
    placeholder = '',
    disabled = false,
    loading = false,
    multiValue = false,
    noMatchesText = 'No matches',
    className = '',
    onEnter,
}) {
    const [isOpen, setIsOpen] = useState(false);
    const ref = useRef<HTMLDivElement | null>(null);

    useEffect(() => {
        function handleClickOutside(e: MouseEvent) {
            if (ref.current && !ref.current.contains(e.target as Node)) {
                setIsOpen(false);
            }
        }
        document.addEventListener('mousedown', handleClickOutside);
        return () => document.removeEventListener('mousedown', handleClickOutside);
    }, []);

    const rawQuery = multiValue ? (value || '').split(',').pop() || '' : (value || '');
    const query = rawQuery.trim().toLowerCase();
    const uniqueOptions = Array.from(new Set((options || []).filter(Boolean)));
    const filteredOptions = uniqueOptions.filter((opt) => opt.toLowerCase().includes(query));

    const handleSelect = (selected: string) => {
        if (multiValue) {
            const chunks = (value || '').split(',');
            const prefix = chunks.slice(0, -1).map((p) => p.trim()).filter(Boolean).join(', ');
            onChange(prefix ? `${prefix}, ${selected}` : selected);
        } else {
            onChange(selected);
        }
        setIsOpen(false);
    };

    return (
        <div ref={ref} className={cx('relative', className)}>
            <input
                type={type}
                id={id}
                className="mono-input w-full"
                placeholder={placeholder}
                value={value}
                onChange={(e) => {
                    onChange(e.target.value);
                    if (!isOpen) setIsOpen(true);
                }}
                onKeyDown={(e) => {
                    if (e.key === 'Enter' && onEnter) onEnter();
                }}
                onFocus={() => setIsOpen(true)}
                onClick={() => setIsOpen(true)}
                disabled={disabled || loading}
            />
            {isOpen && (
                <div className="absolute z-10 w-full mt-1 bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-700 rounded shadow-lg max-h-48 overflow-y-auto">
                    {loading ? (
                        <div className="px-3 py-2 text-sm text-gray-500">Loading...</div>
                    ) : filteredOptions.length === 0 ? (
                        <div className="px-3 py-2 text-sm text-gray-500">{noMatchesText}</div>
                    ) : (
                        filteredOptions.map((opt) => (
                            <button
                                key={opt}
                                type="button"
                                className="w-full text-left px-3 py-2 text-sm hover:bg-gray-100 dark:hover:bg-gray-700"
                                onClick={() => handleSelect(opt)}
                            >
                                {opt}
                            </button>
                        ))
                    )}
                </div>
            )}
        </div>
    );
}

export function ConfirmDialog({
    isOpen,
    onClose,
    onConfirm,
    title,
    message,
    confirmText = 'Confirm',
    cancelText = 'Cancel',
    variant = 'danger',
    requireConfirmation = false,
    confirmationText = '',
    loading = false,
}) {
    const [inputValue, setInputValue] = useState('');
    const [error, setError] = useState('');

    const handleConfirm = () => {
        if (requireConfirmation && inputValue !== confirmationText) {
            setError(`Please type "${confirmationText}" to confirm`);
            return;
        }
        onConfirm();
    };

    const handleClose = () => {
        setInputValue('');
        setError('');
        onClose();
    };

    useEffect(() => {
        if (!isOpen) {
            setInputValue('');
            setError('');
        }
    }, [isOpen]);

    const isConfirmEnabled = !requireConfirmation || inputValue === confirmationText;

    return (
        <Modal isOpen={isOpen} onClose={handleClose} title={title} maxWidth="max-w-md">
            <ModalSection>
                <p className="text-gray-200">{message}</p>

                {requireConfirmation && (
                    <FormField
                        label={`Type "${confirmationText}" to confirm`}
                        id="confirm-input"
                        value={inputValue}
                        onChange={(e) => setInputValue(e.target.value)}
                        error={error}
                        placeholder={confirmationText}
                    />
                )}

                <ModalActions>
                    <Button variant="secondary" onClick={handleClose} disabled={loading}>
                        {cancelText}
                    </Button>
                    <Button variant={variant} onClick={handleConfirm} disabled={!isConfirmEnabled} loading={loading}>
                        {confirmText}
                    </Button>
                </ModalActions>
            </ModalSection>
        </Modal>
    );
}

export function Footer({ version }) {
    return (
        <footer className="mono-footer">
            <div className="mono-footer-inner">
                <div className="flex items-center gap-4">
                    <span>Rise {version?.version ? `v${version.version}` : ''}</span>
                    {version?.repository && (
                        <a href={version.repository} target="_blank" rel="noopener noreferrer" className="underline">
                            github
                        </a>
                    )}
                </div>
                <div className="text-xs">container deployment platform</div>
            </div>
        </footer>
    );
}
