import { useState, useEffect, useRef } from 'react';
import { IconPlus, IconEdit, IconTrash, IconServer, IconWorld, IconMapPin, IconRouter, IconPlug } from '@tabler/icons-react';
import api from '../../lib/api.js';
import { 
  makeGateway, 
  normalizeGateways, 
  needsGateways as NEEDS_GATEWAYS,
  needsTunnel as NEEDS_TUNNEL,
  SERVER_TYPE_OPTIONS,
  TUNNEL_TYPES
} from '../../utils/serverUtils.js';

/**
 * Список провайдеров
 */
const PROVIDER_OPTIONS = [
  { value: '', label: 'Выберите провайдера', disabled: true },
  { value: 'Yandex', label: 'Yandex Cloud' },
  { value: 'Hetzner', label: 'Hetzner' },
  { value: 'VPSVILLE', label: 'VPSVILLE' },
  { value: 'HOSTVDS', label: 'HOSTVDS' },
  { value: 'HIP.hosting', label: 'HIP.hosting' },
  { value: 'Ihor-hosting', label: 'Ihor-hosting' },
  { value: 'DigitalOcean', label: 'DigitalOcean' },
  { value: 'Vultr', label: 'Vultr' },
  { value: 'Linode', label: 'Linode' },
  { value: 'OVH', label: 'OVH' },
  { value: 'AWS', label: 'Amazon Web Services' },
  { value: 'Google', label: 'Google Cloud' },
  { value: 'Azure', label: 'Microsoft Azure' },
  { value: 'Другой', label: 'Другой...' },
];

/**
 * Создаёт пустой объект сервера
 */
const getEmptyServer = () => ({
  id: '',
  ip: '',
  extIp: '',
  internalIp: '',
  dns: '',
  country: '',
  provider: '',
  tunnel: 'GRE',
  type: 'jumphost',
  gateway: '',
  gateways: [makeGateway({ primary: true })],
});

/**
 * Универсальное модальное окно для добавления/редактирования сервера
 * 
 * @param {Object} props
 * @param {boolean} props.show - Показывать ли модальное окно
 * @param {'add'|'edit'} props.mode - Режим работы: 'add' для добавления, 'edit' для редактирования
 * @param {Object} props.server - Данные сервера (для режима редактирования)
 * @param {Function} props.onSave - Callback при сохранении (получает объект сервера)
 * @param {Function} props.onClose - Callback при закрытии
 * @param {string} props.error - Текст ошибки для отображения
 */
function ServerModal({ show, mode = 'add', server, onSave, onClose, error: externalError }) {
  const initializedRef = useRef(false);
  const [localServer, setLocalServer] = useState(getEmptyServer());
  const [customProvider, setCustomProvider] = useState('');
  const [internalError, setInternalError] = useState('');
  const [mikrotikTesting, setMikrotikTesting] = useState(false);
  const [mikrotikTestResult, setMikrotikTestResult] = useState(null);

  const isEditMode = mode === 'edit';
  const error = externalError || internalError;

  /**
   * Подготовка сервера с нормализованными gateways
   */
  const ensureGateways = (srv) => {
    if (!srv) return getEmptyServer();
    const needs = NEEDS_GATEWAYS(srv.type);
    let gateways = [];
    if (needs) {
      gateways = normalizeGateways(srv.gateways, srv.gateway || srv.dns || srv.ip);
      if (gateways.length === 0) {
        gateways = [makeGateway({ primary: true })];
      }
    }
    return { ...srv, gateways };
  };

  /**
   * Инициализация данных при открытии
   */
  useEffect(() => {
    if (show && !initializedRef.current) {
      if (isEditMode && server) {
        const prepared = ensureGateways(server);
        setLocalServer(prepared);
        // Проверяем, нужен ли кастомный провайдер
        const providerExists = PROVIDER_OPTIONS.some(p => p.value === server.provider);
        if (!providerExists && server.provider) {
          setCustomProvider(server.provider);
          setLocalServer(prev => ({ ...prev, provider: 'Другой' }));
        }
      } else {
        setLocalServer(getEmptyServer());
        setCustomProvider('');
      }
      setInternalError('');
      initializedRef.current = true;
    }
    if (!show) {
      initializedRef.current = false;
      setMikrotikTestResult(null);
    }
  }, [show, server, isEditMode]);

  if (!show) return null;

  /**
   * Обработчик изменения поля
   */
  const handleFieldChange = (field, value) => {
    setLocalServer(prev => ({ ...prev, [field]: value }));
  };

  /**
   * Валидация и сохранение
   */
  const handleSubmit = (e) => {
    e.preventDefault();
    setInternalError('');

    // Валидация обязательных полей
    if (!localServer.ip?.trim()) {
      setInternalError('IP адрес обязателен');
      return;
    }
    if (!localServer.dns?.trim()) {
      setInternalError('DNS имя обязательно');
      return;
    }
    if (!localServer.country?.trim()) {
      setInternalError('Страна обязательна');
      return;
    }
    
    // Провайдер
    let finalProvider = localServer.provider;
    if (localServer.provider === 'Другой') {
      if (!customProvider.trim()) {
        setInternalError('Введите название провайдера');
        return;
      }
      finalProvider = customProvider.trim();
    }
    if (!finalProvider) {
      setInternalError('Провайдер обязателен');
      return;
    }

    // Шлюзы для jumphost/exit задаются в другом месте (network-config); при сохранении передаём существующие или один по умолчанию
    const needsGws = NEEDS_GATEWAYS(localServer.type);
    let finalGateways = [];
    if (needsGws) {
      finalGateways = normalizeGateways(localServer.gateways, localServer.gateway || localServer.dns || localServer.ip);
      if (finalGateways.length === 0) {
        finalGateways = [makeGateway({ primary: true, name: localServer.dns?.split('.')[0] || 'main' })];
      }
    }

    const serverToSave = {
      ...localServer,
      provider: finalProvider,
      gateways: finalGateways,
    };

    onSave && onSave(serverToSave);
  };

  return (
    <>
      <div className="modal-backdrop show" onClick={onClose} />
      <div className="modal show d-block" tabIndex="-1">
      <div className="modal-dialog modal-lg">
        <div className="modal-content">
          <div className="modal-header">
            <h5 className="modal-title d-flex align-items-center">
              {isEditMode ? (
                <>
                  <IconEdit className="icon me-2" />
                  Редактировать сервер
                </>
              ) : (
                <>
                  <IconPlus className="icon me-2" />
                  Добавить новый сервер
                </>
              )}
            </h5>
            <button type="button" className="btn-close" onClick={onClose} aria-label="Close"></button>
          </div>
          
          <form onSubmit={handleSubmit}>
            <div className="modal-body">
              {error && (
                <div className="alert alert-danger mb-3" role="alert">
                  {error}
                </div>
              )}

              <div className="row g-3">
                {/* ID - опционально */}
                <div className="col-md-4">
                  <label className="form-label">
                    ID <span className="text-muted">(опционально)</span>
                  </label>
                  <input
                    type="text"
                    className="form-control"
                    value={localServer.id || ''}
                    onChange={(e) => handleFieldChange('id', e.target.value)}
                    placeholder="srv-1"
                  />
                </div>

                {/* IP адрес */}
                <div className="col-md-4">
                  <label className="form-label required">IP адрес</label>
                  <div className="input-icon">
                    <span className="input-icon-addon">
                      <IconServer size={16} />
                    </span>
                    <input
                      type="text"
                      className="form-control"
                      value={localServer.ip || ''}
                      onChange={(e) => handleFieldChange('ip', e.target.value)}
                      placeholder="192.168.1.1"
                      required
                    />
                  </div>
                </div>

                {/* DNS */}
                <div className="col-md-4">
                  <label className="form-label required">DNS имя</label>
                  <div className="input-icon">
                    <span className="input-icon-addon">
                      <IconWorld size={16} />
                    </span>
                    <input
                      type="text"
                      className="form-control"
                      value={localServer.dns || ''}
                      onChange={(e) => handleFieldChange('dns', e.target.value)}
                      placeholder="srv1.example.com"
                      required
                    />
                  </div>
                </div>

                {/* Внешний IP */}
                <div className="col-md-6">
                  <label className="form-label">
                    Внешний IP <span className="text-muted">(опционально)</span>
                  </label>
                  <input
                    type="text"
                    className="form-control"
                    value={localServer.extIp || ''}
                    onChange={(e) => handleFieldChange('extIp', e.target.value)}
                    placeholder="Публичный IP, если отличается"
                  />
                </div>

                {/* Внутренний IP */}
                <div className="col-md-6">
                  <label className="form-label">
                    Внутренний IP <span className="text-muted">(опционально)</span>
                  </label>
                  <input
                    type="text"
                    className="form-control"
                    value={localServer.internalIp || ''}
                    onChange={(e) => handleFieldChange('internalIp', e.target.value)}
                    placeholder="10.x.x.x / 192.168.x.x"
                  />
                </div>

                {/* Страна — 2-буквенный код как в интерфейсах */}
                <div className="col-md-6">
                  <label className="form-label required">Страна</label>
                  <div className="input-icon">
                    <span className="input-icon-addon">
                      <IconMapPin size={16} />
                    </span>
                    <input
                      type="text"
                      className="form-control ps-8"
                      value={localServer.country || ''}
                      onChange={(e) => handleFieldChange('country', e.target.value.toUpperCase().slice(0, 2))}
                      placeholder="RU, SE, DE…"
                      maxLength={2}
                      required
                    />
                  </div>
                  <div className="form-text">2-буквенный код страны (ISO 3166-1 alpha-2)</div>
                </div>

                {/* Провайдер */}
                <div className="col-md-6">
                  <label className="form-label required">Провайдер</label>
                  <select
                    className="form-select"
                    value={localServer.provider || ''}
                    onChange={(e) => handleFieldChange('provider', e.target.value)}
                    required
                  >
                    {PROVIDER_OPTIONS.map((opt) => (
                      <option key={opt.value} value={opt.value} disabled={opt.disabled}>
                        {opt.label}
                      </option>
                    ))}
                  </select>
                </div>

                {/* Кастомный провайдер */}
                {localServer.provider === 'Другой' && (
                  <div className="col-12">
                    <label className="form-label required">Название провайдера</label>
                    <input
                      type="text"
                      className="form-control"
                      value={customProvider}
                      onChange={(e) => setCustomProvider(e.target.value)}
                      placeholder="Введите название провайдера"
                      required
                    />
                  </div>
                )}

                {/* Тип сервера */}
                <div className={NEEDS_TUNNEL(localServer.type) ? "col-md-6" : "col-12"}>
                  <label className="form-label required">Тип сервера</label>
                  <select
                    className="form-select"
                    value={localServer.type || 'jumphost'}
                    onChange={(e) => handleFieldChange('type', e.target.value)}
                    required
                  >
                    {SERVER_TYPE_OPTIONS.map((opt) => (
                      <option key={opt.value} value={opt.value}>
                        {opt.label}
                      </option>
                    ))}
                  </select>
                </div>

                {/* Тип туннеля - только для типов, которым он нужен */}
                {NEEDS_TUNNEL(localServer.type) && (
                  <div className="col-md-6">
                    <label className="form-label required">Тип туннеля</label>
                    <select
                      className="form-select"
                      value={localServer.tunnel || 'GRE'}
                      onChange={(e) => handleFieldChange('tunnel', e.target.value)}
                      required
                    >
                      {TUNNEL_TYPES.map((t) => (
                        <option key={t} value={t}>{t}</option>
                      ))}
                    </select>
                  </div>
                )}

                {/* Группа объединения — для домашнего роутера с мультиваном: один ключ у нескольких записей = одна карточка в списке */}
                {localServer.type === 'home' && (
                  <div className="col-12">
                    <label className="form-label">
                      Группа (объединение в списке)
                    </label>
                    <input
                      type="text"
                      className="form-control"
                      value={localServer.groupKey || ''}
                      onChange={(e) => {
                      const v = e.target.value.trim();
                      handleFieldChange('groupKey', v || '');
                    }}
                      placeholder="Например: home-multivan — две записи с одним ключом отобразятся как один роутер"
                    />
                    <div className="form-text">
                      Укажите одинаковый ключ у обоих WAN-записей одного роутера, чтобы в разделе «Серверы» они отображались одной карточкой. ID и привязки (интерфейсы, фильтры) не меняются.
                    </div>
                  </div>
                )}

              </div>

              {/* MikroTik RouterOS API — для jumphost и домашних (входных) роутеров */}
              {(localServer.type === 'jumphost' || localServer.type === 'home') && (
                <div className="mt-4 pt-3 border-top">
                  <label className="form-label d-flex align-items-center gap-2">
                    <IconRouter size={18} />
                    MikroTik RouterOS API
                  </label>
                  <div className="row g-3">
                    <div className="col-md-4">
                      <label className="form-label small">Хост</label>
                      <input
                        type="text"
                        className="form-control form-control-sm"
                        value={localServer.mikrotikHost || ''}
                        onChange={(e) => handleFieldChange('mikrotikHost', e.target.value)}
                        placeholder={localServer.ip || 'IP или DNS'}
                      />
                    </div>
                    <div className="col-md-2">
                      <label className="form-label small">Порт</label>
                      <input
                        type="number"
                        className="form-control form-control-sm"
                        value={localServer.mikrotikPort || '80'}
                        onChange={(e) => handleFieldChange('mikrotikPort', e.target.value)}
                        placeholder="80"
                      />
                    </div>
                    <div className="col-md-3">
                      <label className="form-label small">Пользователь</label>
                      <input
                        type="text"
                        className="form-control form-control-sm"
                        value={localServer.mikrotikUser || 'admin'}
                        onChange={(e) => handleFieldChange('mikrotikUser', e.target.value)}
                        placeholder="admin"
                      />
                    </div>
                    <div className="col-md-3">
                      <label className="form-label small">Пароль</label>
                      <input
                        type="password"
                        className="form-control form-control-sm"
                        value={localServer.mikrotikPassword ?? ''}
                        onChange={(e) => handleFieldChange('mikrotikPassword', e.target.value)}
                        placeholder={localServer.hasMikrotikPassword ? '••••••' : 'Введите пароль'}
                      />
                    </div>
                  </div>
                  <div className="mt-2 d-flex align-items-center gap-2">
                    <button
                      type="button"
                      className="btn btn-outline-primary btn-sm d-flex align-items-center gap-1"
                      disabled={mikrotikTesting || !(localServer.mikrotikHost || localServer.ip)}
                      onClick={async () => {
                        setMikrotikTestResult(null);
                        setMikrotikTesting(true);
                        try {
                          const hasPassword = localServer.mikrotikPassword && String(localServer.mikrotikPassword).trim() !== '';
                          const payload = hasPassword
                            ? {
                                host: localServer.mikrotikHost || localServer.ip,
                                port: localServer.mikrotikPort || 80,
                                user: localServer.mikrotikUser || 'admin',
                                password: localServer.mikrotikPassword,
                              }
                            : (localServer.hasMikrotikPassword && (localServer.id || localServer.dns || localServer.ip))
                              ? { serverId: localServer.id || localServer.dns || localServer.ip }
                              : null;
                          if (!payload) {
                            setMikrotikTestResult({ ok: false, message: 'Введите пароль или сохраните сервер с паролем' });
                            return;
                          }
                          const { data } = await api.post('/mikrotik/test-connection', payload);
                          setMikrotikTestResult(data);
                        } catch (err) {
                          setMikrotikTestResult({
                            ok: false,
                            message: err.response?.data?.message || err.message || 'Ошибка соединения',
                          });
                        } finally {
                          setMikrotikTesting(false);
                        }
                      }}
                    >
                      <IconPlug size={14} />
                      {mikrotikTesting ? 'Проверка...' : 'Проверить соединение'}
                    </button>
                    {mikrotikTestResult && (
                      <span className={mikrotikTestResult.ok ? 'text-success' : 'text-danger'}>
                        {mikrotikTestResult.ok ? '✓ ' + (mikrotikTestResult.message || 'OK') : '✗ ' + mikrotikTestResult.message}
                      </span>
                    )}
                  </div>
                </div>
              )}
            </div>

            <div className="modal-footer">
              <button type="button" className="btn btn-secondary" onClick={onClose}>
                Отмена
              </button>
              <button type="submit" className="btn btn-primary d-flex align-items-center">
                {isEditMode ? (
                  <>
                    <IconEdit size={16} className="me-1" />
                    Сохранить
                  </>
                ) : (
                  <>
                    <IconPlus size={16} className="me-1" />
                    Добавить сервер
                  </>
                )}
              </button>
            </div>
          </form>
        </div>
      </div>
      </div>
    </>
  );
}

export default ServerModal;
