import React, {useState, useEffect, useContext} from 'react';
import {UserContext} from '@/common/contexts/UserContext.jsx';
import {useToast} from '@/common/contexts/ToastContext.jsx';
import {getRequest, postRequest} from '@/common/utils/RequestUtil.js';
import Button from '@/common/components/Button';
import Input from '@/common/components/Input';
import Card, {CardHeader, CardBody} from '@/common/components/Card';
import LoadingSpinner from '@/common/components/LoadingSpinner';
import PageHeader from '@/common/components/PageHeader';
import {
    SlidersIcon,
    FloppyDiskIcon,
    ArrowClockwiseIcon,
    InfoIcon,
    WarningIcon
} from '@phosphor-icons/react';
import './styles.sass';

export const SystemSettings = () => {
    const toast = useToast();
    const [configs, setConfigs] = useState([]);
    const [loading, setLoading] = useState(true);
    const [formData, setFormData] = useState({});
    const [formErrors, setFormErrors] = useState({});
    const [submitting, setSubmitting] = useState(false);
    const [hasChanges, setHasChanges] = useState(false);

    useEffect(() => {
        fetchConfigs();
    }, []);

    const fetchConfigs = async () => {
        try {
            setLoading(true);
            const response = await getRequest('admin/config');
            setConfigs(response.configs);

            const initialData = {};
            response.configs.forEach(config => {
                initialData[config.key] = config.value || config.default_value || '';
            });
            setFormData(initialData);
            setHasChanges(false);
        } catch (error) {
            console.error('Failed to fetch configs:', error);
            toast.error('Failed to load system settings. Please try again.');
        } finally {
            setLoading(false);
        }
    };

    const handleInputChange = (key, value) => {
        setFormData(prev => {
            const newData = {...prev, [key]: value};

            const originalConfig = configs.find(c => c.key === key);
            const hasChange = Object.keys(newData).some(k => {
                const original = configs.find(c => c.key === k);
                const origVal = original?.value || original?.default_value || '';
                return newData[k] !== origVal;
            });

            setHasChanges(hasChange);
            return newData;
        });

        if (formErrors[key]) {
            setFormErrors(prev => ({
                ...prev,
                [key]: ''
            }));
        }
    };

    const validateForm = () => {
        const errors = {};

        configs.forEach(config => {
            const value = formData[config.key] || '';

            if (config.required && !value.trim()) {
                errors[config.key] = `${config.key} is required`;
                return;
            }

            switch (config.key) {
                case 'EXTERNAL_URL':
                    if (value && !value.startsWith('http://') && !value.startsWith('https://')) {
                        errors[config.key] = 'URL must start with http:// or https://';
                    }
                    break;
                case 'MAX_UPLOAD_SIZE_MB':
                case 'BACKUP_RETENTION_DAYS':
                case 'SESSION_TIMEOUT_HOURS':
                    if (value && (isNaN(value) || parseInt(value) <= 0)) {
                        errors[config.key] = 'Must be a positive number';
                    }
                    break;
            }
        });

        setFormErrors(errors);
        return Object.keys(errors).length === 0;
    };

    const handleSave = async () => {
        if (!validateForm()) {
            return;
        }

        setSubmitting(true);

        try {
            const savePromises = [];

            for (const config of configs) {
                const newValue = formData[config.key] || '';
                const originalValue = config.value || config.default_value || '';

                if (newValue !== originalValue) {
                    savePromises.push(
                        postRequest('admin/config', {
                            key: config.key,
                            value: newValue
                        })
                    );
                }
            }

            await Promise.all(savePromises);

            toast.success('System settings saved successfully');
            setHasChanges(false);
            await fetchConfigs();
        } catch (error) {
            console.error('Failed to save settings:', error);
            const errorMessage = error.error || 'Failed to save settings. Please try again.';
            toast.error(errorMessage);
        } finally {
            setSubmitting(false);
        }
    };

    const handleReset = async () => {
        if (!window.confirm('Are you sure you want to reset all settings to their current saved values? Any unsaved changes will be lost.')) {
            return;
        }

        await fetchConfigs();
        toast.info('Settings reset to saved values');
    };

    const getFieldType = (key) => {
        switch (key) {
            case 'SESSION_TIMEOUT_HOURS':
                return 'number';
            case 'EXTERNAL_URL':
                return 'url';
            default:
                return 'text';
        }
    };

    const getFieldPlaceholder = (config) => {
        if (config.default_value) {
            return `Default: ${config.default_value}`;
        }
        return `Enter ${config.key.toLowerCase().replace(/_/g, ' ')}`;
    };

    if (loading) {
        return (
            <div className="content">
                <LoadingSpinner centered text="Loading system settings..."/>
            </div>
        );
    }

    return (
        <div className="content">
            <PageHeader
                title="System Settings"
                subtitle="Configure system-wide settings and preferences"
                actions={
                    <div className="settings-actions">
                        <Button
                            variant="subtle"
                            icon={<ArrowClockwiseIcon size={16}/>}
                            onClick={handleReset}
                            disabled={submitting || !hasChanges}
                        >
                            Reset
                        </Button>
                        <Button
                            variant="primary"
                            icon={<FloppyDiskIcon size={16}/>}
                            onClick={handleSave}
                            loading={submitting}
                            disabled={submitting || !hasChanges}
                        >
                            Save Changes
                        </Button>
                    </div>
                }
            />

            {hasChanges && (
                <div className="settings-notice">
                    <WarningIcon size={16}/>
                    <span>You have unsaved changes</span>
                </div>
            )}

            <div className="settings-grid">
                {configs.map(config => (
                    <Card key={config.key} className="setting-card">
                        <CardHeader>
                            <div className="setting-header">
                                <div className="setting-info">
                                    <h3 className="setting-title">
                                        {config.key.replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase())}
                                        {config.required && <span className="required">*</span>}
                                    </h3>
                                    <p className="setting-description">{config.description}</p>
                                </div>
                                {config.default_value && (
                                    <div className="setting-default">
                                        <InfoIcon size={14}/>
                                        <span>Default: {config.default_value}</span>
                                    </div>
                                )}
                            </div>
                        </CardHeader>

                        <CardBody>
                            <Input
                                type={getFieldType(config.key)}
                                value={formData[config.key] || ''}
                                onChange={(e) => handleInputChange(config.key, e.target.value)}
                                placeholder={getFieldPlaceholder(config)}
                                error={formErrors[config.key]}
                                disabled={submitting}
                                className="setting-input"
                            />
                        </CardBody>
                    </Card>
                ))}
            </div>

            {configs.length === 0 && (
                <Card>
                    <CardBody>
                        <div className="empty-settings">
                            <SlidersIcon size={48} weight="duotone"/>
                            <h3>No settings available</h3>
                            <p>No configurable settings are currently defined.</p>
                        </div>
                    </CardBody>
                </Card>
            )}
        </div>
    );
};