import React, { useEffect, useState, useRef } from 'react';
import { useTranslation } from 'react-i18next';
import {
  Button,
  Divider,
  Form,
  Grid,
  Header,
  Label,
  Message,
  Icon,
} from 'semantic-ui-react';
import { API, showError, showSuccess } from '../helpers';

const ServerConfigSetting = () => {
  const { t } = useTranslation();
  const [configs, setConfigs] = useState([]);
  const [loading, setLoading] = useState(false);
  const [downloadLoading, setDownloadLoading] = useState(false);
  const fileInputRef = useRef(null);

  const getConfigs = async () => {
    setLoading(true);
    const res = await API.get('/api/server/config/');
    const { success, message, data } = res.data;
    if (success) {
      setConfigs(data);
    } else {
      showError(message);
    }
    setLoading(false);
  };

  useEffect(() => {
    getConfigs().then();
  }, []);

  // Group configs by category
  const categories = [
    { key: 'database', icon: 'database' },
    { key: 'redis', icon: 'server' },
    { key: 'performance', icon: 'tachometer alternate' },
    { key: 'network', icon: 'globe' },
    { key: 'ratelimit', icon: 'clock' },
    { key: 'metrics', icon: 'chart line' },
    { key: 'other', icon: 'cog' },
  ];

  const getConfigsByCategory = (category) => {
    return configs.filter((item) => item.category === category);
  };

  const isSecretKey = (key) => {
    const secretKeys = [
      'SESSION_SECRET',
      'REDIS_PASSWORD',
      'REDIS_CONN_STRING',
      'SQL_DSN',
      'LOG_SQL_DSN',
      'HTTPS_PROXY',
    ];
    return secretKeys.includes(key);
  };

  const isBooleanKey = (key) => {
    const booleanKeys = [
      'DEBUG',
      'DEBUG_SQL',
      'MEMORY_CACHE_ENABLED',
      'BATCH_UPDATE_ENABLED',
      'ENABLE_METRIC',
      'ONLY_ONE_LOG_FILE',
      'ENFORCE_INCLUDE_USAGE',
    ];
    return booleanKeys.includes(key);
  };

  const isNumericKey = (key) => {
    const numericKeys = [
      'BATCH_UPDATE_INTERVAL',
      'RELAY_TIMEOUT',
      'USER_CONTENT_REQUEST_TIMEOUT',
      'GLOBAL_API_RATE_LIMIT',
      'GLOBAL_WEB_RATE_LIMIT',
      'METRIC_QUEUE_SIZE',
      'METRIC_SUCCESS_RATE_THRESHOLD',
      'PORT',
      'SQLITE_BUSY_TIMEOUT',
      'SQL_MAX_IDLE_CONNS',
      'SQL_MAX_OPEN_CONNS',
      'SQL_MAX_LIFETIME',
      'SYNC_FREQUENCY',
      'CHANNEL_TEST_FREQUENCY',
    ];
    return numericKeys.includes(key);
  };

  const getCategoryTitle = (catKey) => {
    const titles = {
      database: t('setting.server_config.categories.database'),
      redis: t('setting.server_config.categories.redis'),
      performance: t('setting.server_config.categories.performance'),
      network: t('setting.server_config.categories.network'),
      ratelimit: t('setting.server_config.categories.ratelimit'),
      metrics: t('setting.server_config.categories.metrics'),
      other: t('setting.server_config.categories.other'),
    };
    return titles[catKey] || catKey;
  };

  const handleValueChange = (key, value) => {
    setConfigs((prev) =>
      prev.map((item) => (item.key === key ? { ...item, value } : item))
    );
  };

  const updateConfig = async (key, value) => {
    setLoading(true);
    const res = await API.put('/api/server/config/', { key, value });
    const { success, message } = res.data;
    if (success) {
      showSuccess(t('setting.server_config.messages.save_success'));
    } else {
      showError(message);
      // Revert value on failure
      getConfigs().then();
    }
    setLoading(false);
  };

  const handleSaveRuntime = async (key) => {
    const item = configs.find((c) => c.key === key);
    if (!item) return;
    let value = item.value;
    if (isBooleanKey(key)) {
      value = value === 'true' ? 'true' : 'false';
    }
    await updateConfig(key, value);
  };

  const handleToggle = async (key) => {
    const item = configs.find((c) => c.key === key);
    if (!item) return;
    const newValue = item.value === 'true' ? 'false' : 'true';
    setConfigs((prev) =>
      prev.map((c) => (c.key === key ? { ...c, value: newValue } : c))
    );
    await updateConfig(key, newValue);
  };

  const handleDownloadEnv = async () => {
    setDownloadLoading(true);
    try {
      const res = await API.get('/api/server/config/download', {
        responseType: 'blob',
      });
      const url = window.URL.createObjectURL(new Blob([res.data]));
      const link = document.createElement('a');
      link.href = url;
      link.setAttribute('download', 'server-config.env');
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      window.URL.revokeObjectURL(url);
      showSuccess(t('setting.server_config.messages.download_success'));
    } catch (error) {
      showError(t('setting.server_config.messages.download_error'));
    }
    setDownloadLoading(false);
  };

  const handleImportClick = () => {
    fileInputRef.current?.click();
  };

  const handleImportEnv = async (e) => {
    const file = e.target.files[0];
    if (!file) return;

    const formData = new FormData();
    formData.append('file', file);

    setLoading(true);
    try {
      const res = await API.post('/api/server/config/import', formData, {
        headers: { 'Content-Type': 'multipart/form-data' },
      });
      const { success, message } = res.data;
      if (success) {
        showSuccess(message);
      } else {
        showError(message);
      }
    } catch (error) {
      showError(t('setting.server_config.messages.import_error'));
    }
    setLoading(false);
    e.target.value = '';
  };

  const renderConfigInput = (item) => {
    const { key, value, restart_required } = item;

    if (isBooleanKey(key)) {
      return (
        <Form.Group inline key={key}>
          <Form.Checkbox
            checked={value === 'true'}
            label={
              <label>
                {key}
                {restart_required && (
                  <Label
                    size='tiny'
                    color='yellow'
                    style={{ marginLeft: 8 }}
                  >
                    <Icon name='refresh' />
                    {t('setting.server_config.restart_required')}
                  </Label>
                )}
              </label>
            }
            onChange={() => handleToggle(key)}
          />
        </Form.Group>
      );
    }

    // For database type, show as read-only
    if (key === 'db_type') {
      return (
        <Form.Group widths='equal' key={key}>
          <Form.Input
            label={
              <label>
                {key}
                {restart_required && (
                  <Label
                    size='tiny'
                    color='yellow'
                    style={{ marginLeft: 8 }}
                  >
                    <Icon name='refresh' />
                    {t('setting.server_config.restart_required')}
                  </Label>
                )}
              </label>
            }
            value={value}
            readOnly
            icon='info circle'
            iconPosition='left'
          />
        </Form.Group>
      );
    }

    return (
      <Form.Group widths='equal' key={key}>
        <Form.Input
          label={
            <label>
              {key}
              {restart_required && (
                <Label
                  size='tiny'
                  color='yellow'
                  style={{ marginLeft: 8 }}
                >
                  <Icon name='refresh' />
                  {t('setting.server_config.restart_required')}
                </Label>
              )}
            </label>
          }
          placeholder={item.default_value}
          value={value}
          type={isSecretKey(key) ? 'password' : isNumericKey(key) ? 'number' : 'text'}
          onChange={(e, { value: v }) => handleValueChange(key, v)}
          action={
            !restart_required && (
              <Button
                color='green'
                onClick={() => handleSaveRuntime(key)}
              >
                {t('setting.server_config.buttons.save')}
              </Button>
            )
          }
        />
      </Form.Group>
    );
  };

  return (
    <Grid columns={1}>
      <Grid.Column>
        <Message info>
          <Message.Header>
            <Icon name='info circle' />
            {t('setting.server_config.notice_title')}
          </Message.Header>
          <p>{t('setting.server_config.notice_content')}</p>
        </Message>

        <div style={{ marginBottom: 20 }}>
          <Button
            color='blue'
            loading={downloadLoading}
            onClick={handleDownloadEnv}
            style={{ marginRight: 10 }}
          >
            <Icon name='download' />
            {t('setting.server_config.buttons.download_env')}
          </Button>
          <Button
            color='teal'
            onClick={handleImportClick}
          >
            <Icon name='upload' />
            {t('setting.server_config.buttons.import_env')}
          </Button>
          <input
            ref={fileInputRef}
            type='file'
            accept='.env,.txt'
            style={{ display: 'none' }}
            onChange={handleImportEnv}
          />
          <Button
            color='grey'
            onClick={getConfigs}
            style={{ marginLeft: 10 }}
          >
            <Icon name='refresh' />
            {t('setting.server_config.buttons.refresh')}
          </Button>
        </div>

        <Form loading={loading}>
          {categories.map((cat) => {
            const catConfigs = getConfigsByCategory(cat.key);
            if (catConfigs.length === 0) return null;

            return (
              <div key={cat.key}>
                <Header as='h3'>
                  <Icon name={cat.icon} />
                  <Header.Content>
                    {getCategoryTitle(cat.key)}
                    <Header.Subheader>
                      {t('setting.server_config.count', {
                        count: catConfigs.length,
                      })}
                    </Header.Subheader>
                  </Header.Content>
                </Header>

                {catConfigs.map((item) => renderConfigInput(item))}

                <Divider />
              </div>
            );
          })}
        </Form>
      </Grid.Column>
    </Grid>
  );
};

export default ServerConfigSetting;