import { useEffect, useRef, useState } from 'react';
import {
  signInWithTelegram,
  verifyAuth,
  fetchUsers,
  banUser,
  fetchPosts,
  updatePost,
  deletePost,
  removePostImage,
  banPostAuthor,
  fetchReports,
  updateReportStatus,
  publishToChannel
} from './utils/api';
import { io } from 'socket.io-client';
import {
  Loader2,
  Users,
  Image as ImageIcon,
  ShieldCheck,
  SendHorizontal,
  MessageSquare,
  RefreshCw,
  Trash2,
  Edit,
  Ban
} from 'lucide-react';

const TABS = [
  { id: 'users', title: 'Пользователи', icon: Users },
  { id: 'posts', title: 'Посты', icon: ImageIcon },
  { id: 'reports', title: 'Репорты', icon: ShieldCheck },
  { id: 'chat', title: 'Чат', icon: MessageSquare },
  { id: 'publish', title: 'Публикация', icon: SendHorizontal }
];

const FILTERS = [
  { id: 'active', label: 'Активные < 7д' },
  { id: 'inactive', label: 'Неактивные' },
  { id: 'banned', label: 'Бан' }
];

const slotOptions = Array.from({ length: 10 }, (_, i) => i + 1);

const initialChatState = {
  messages: [],
  online: [],
  connected: false
};

function formatDate(dateString) {
  if (!dateString) return '—';
  const date = new Date(dateString);
  return date.toLocaleString('ru-RU', {
    day: '2-digit',
    month: 'short',
    hour: '2-digit',
    minute: '2-digit'
  });
}

function classNames(...args) {
  return args.filter(Boolean).join(' ');
}

export default function App() {
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);
  const [tab, setTab] = useState('users');

  // Users
  const [userFilter, setUserFilter] = useState('active');
  const [usersData, setUsersData] = useState({ users: [], total: 0, totalPages: 1 });
  const [usersLoading, setUsersLoading] = useState(false);

  // Posts
  const [postsData, setPostsData] = useState({ posts: [], totalPages: 1 });
  const [postsLoading, setPostsLoading] = useState(false);

  // Reports
  const [reportsData, setReportsData] = useState({ reports: [], totalPages: 1 });
  const [reportsLoading, setReportsLoading] = useState(false);

  // Publish
  const [publishState, setPublishState] = useState({
    description: '',
    tags: '',
    slot: 1,
    files: []
  });
  const [publishing, setPublishing] = useState(false);

  // Chat
  const [chatState, setChatState] = useState(initialChatState);
  const [chatInput, setChatInput] = useState('');
  const chatSocketRef = useRef(null);
  const chatListRef = useRef(null);

  useEffect(() => {
    let cancelled = false;

    const waitForInitData = async () => {
      const start = Date.now();
      const timeout = 5000;

      while (Date.now() - start < timeout) {
        const app = window.Telegram?.WebApp;
        if (app?.initData && app.initData.length > 0) {
          return app;
        }
        await new Promise((resolve) => setTimeout(resolve, 100));
      }
      throw new Error('Telegram initData не передан (timeout)');
    };

    const init = async () => {
      try {
        const telegramApp = window.Telegram?.WebApp;

        if (!telegramApp) {
          throw new Error('Откройте модераторский интерфейс из Telegram (бот @rbachbot).');
        }

        telegramApp.disableVerticalSwipes?.();
        telegramApp.ready?.();
        telegramApp.expand?.();

        const app = await waitForInitData();
        if (cancelled) return;

        const initData = app.initData;

        if (!initData) {
          throw new Error('Telegram не передал initData');
        }

        const userData = await signInWithTelegram(initData);
        if (cancelled) return;

        setUser(userData);
        setError(null);
      } catch (err) {
        if (cancelled) return;
        console.error('Ошибка инициализации модератора:', err);
        try {
          const userData = await verifyAuth();
          if (!cancelled) {
            setUser(userData);
            setError(null);
          }
        } catch (verifyError) {
          if (!cancelled) {
            const message =
              err?.response?.data?.error ||
              verifyError?.response?.data?.error ||
              err?.message ||
              'Нет доступа. Убедитесь, что вы добавлены как администратор.';
            setError(message);
          }
        }
      } finally {
        if (!cancelled) {
          setLoading(false);
          const telegramApp = window.Telegram?.WebApp;
          telegramApp?.MainButton?.setText?.('Закрыть');
          telegramApp?.MainButton?.show?.();
          telegramApp?.MainButton?.onClick?.(() => telegramApp.close());
        }
      }
    };

    init();

    return () => {
      cancelled = true;
      window.Telegram?.WebApp?.MainButton?.hide?.();
    };
  }, []);

  useEffect(() => {
    if (tab === 'users') {
      loadUsers();
    } else if (tab === 'posts') {
      loadPosts();
    } else if (tab === 'reports') {
      loadReports();
    } else if (tab === 'chat' && user) {
      initChat();
    }

    return () => {
      if (tab !== 'chat' && chatSocketRef.current) {
        chatSocketRef.current.disconnect();
        chatSocketRef.current = null;
        setChatState(initialChatState);
      }
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [tab, user, userFilter]);

  const loadUsers = async () => {
    setUsersLoading(true);
    try {
      const data = await fetchUsers({ filter: userFilter });
      setUsersData(data);
    } catch (err) {
      console.error(err);
    } finally {
      setUsersLoading(false);
    }
  };

  const loadPosts = async () => {
    setPostsLoading(true);
    try {
      const data = await fetchPosts();
      setPostsData(data);
    } catch (err) {
      console.error(err);
    } finally {
      setPostsLoading(false);
    }
  };

  const loadReports = async () => {
    setReportsLoading(true);
    try {
      const data = await fetchReports();
      setReportsData(data);
    } catch (err) {
      console.error(err);
    } finally {
      setReportsLoading(false);
    }
  };

  const initChat = () => {
    if (!user || chatSocketRef.current) return;
    const socket = io('/mod-chat', {
      transports: ['websocket', 'polling']
    });

    socket.on('connect', () => {
      socket.emit('auth', {
        username: user.username,
        telegramId: user.telegramId
      });
    });

    socket.on('ready', () => {
      setChatState((prev) => ({ ...prev, connected: true }));
    });

    socket.on('unauthorized', () => {
      setChatState((prev) => ({ ...prev, connected: false }));
      socket.disconnect();
    });

    socket.on('message', (message) => {
      setChatState((prev) => ({
        ...prev,
        messages: [...prev.messages, message]
      }));
      if (chatListRef.current) {
        chatListRef.current.scrollTo({
          top: chatListRef.current.scrollHeight,
          behavior: 'smooth'
        });
      }
    });

    socket.on('online', (online) => {
      setChatState((prev) => ({ ...prev, online }));
    });

    socket.on('disconnect', () => {
      setChatState((prev) => ({ ...prev, connected: false }));
    });

    chatSocketRef.current = socket;
  };

  const handleSendChat = () => {
    if (!chatSocketRef.current || !chatState.connected) return;
    const text = chatInput.trim();
    if (!text) return;
    chatSocketRef.current.emit('message', { text });
    setChatInput('');
  };

  const handleBanUser = async (id, banned) => {
    const days = banned ? parseInt(prompt('Введите срок бана в днях', '7'), 10) : 0;
    await banUser(id, { banned, days });
    loadUsers();
  };

  const handlePostEdit = async (post) => {
    const newContent = prompt('Новый текст поста', post.content || '');
    if (newContent === null) return;
    await updatePost(post.id, { content: newContent });
    loadPosts();
  };

  const handlePostDelete = async (postId) => {
    if (!window.confirm('Удалить пост?')) return;
    await deletePost(postId);
    loadPosts();
  };

  const handleRemoveImage = async (postId, index) => {
    await removePostImage(postId, index);
    loadPosts();
  };

  const handleBanAuthor = async (postId) => {
    const days = parseInt(prompt('Срок бана автора (в днях)', '7'), 10);
    await banPostAuthor(postId, { days });
    loadPosts();
    loadUsers();
  };

  const handleReportStatus = async (reportId, status) => {
    await updateReportStatus(reportId, { status });
    loadReports();
  };

  const handlePublish = async () => {
    if (!publishState.files.length) {
      alert('Добавьте изображения');
      return;
    }

    setPublishing(true);
    try {
      const formData = new FormData();
      publishState.files.forEach((file) => formData.append('images', file));
      formData.append('description', publishState.description);
      formData.append('tags', JSON.stringify(
        publishState.tags
          .split(/[,\s]+/)
          .map((tag) => tag.trim())
          .filter(Boolean)
      ));
      formData.append('slot', publishState.slot);

      await publishToChannel(formData);
      setPublishState({
        description: '',
        tags: '',
        slot: 1,
        files: []
      });
      alert('Опубликовано в канал @reichenbfurry');
    } catch (err) {
      console.error(err);
      alert('Не удалось опубликовать пост');
    } finally {
      setPublishing(false);
    }
  };

  const handleFileChange = (event) => {
    const files = Array.from(event.target.files || []).slice(0, 10);
    setPublishState((prev) => ({ ...prev, files }));
  };

  const renderUsers = () => (
    <div className="card">
      <div className="section-header">
        <h2>Пользователи</h2>
        <button className="icon-btn" onClick={loadUsers} disabled={usersLoading}>
          <RefreshCw size={18} />
        </button>
      </div>
      <div className="filter-chips">
        {FILTERS.map((filter) => (
          <button
            key={filter.id}
            className={classNames('chip', userFilter === filter.id && 'chip-active')}
            onClick={() => setUserFilter(filter.id)}
          >
            {filter.label}
          </button>
        ))}
      </div>

      {usersLoading ? (
        <div className="loader">
          <Loader2 className="spin" size={32} />
        </div>
      ) : (
        <div className="list">
          {usersData.users.map((u) => (
            <div key={u.id} className="list-item">
              <div className="list-item-main">
                <div className="list-item-title">@{u.username}</div>
                <div className="list-item-subtitle">
                  {u.firstName} {u.lastName || ''}
                </div>
                <div className="list-item-meta">
                  <span>Роль: {u.role}</span>
                  <span>Активность: {formatDate(u.lastActiveAt)}</span>
                  {u.banned && <span className="badge badge-danger">Бан до {formatDate(u.bannedUntil)}</span>}
                </div>
              </div>
              <div className="list-item-actions">
                {u.banned ? (
                  <button className="btn" onClick={() => handleBanUser(u.id, false)}>
                    Разблокировать
                  </button>
                ) : (
                  <button className="btn danger" onClick={() => handleBanUser(u.id, true)}>
                    Забанить
                  </button>
                )}
              </div>
            </div>
          ))}
        </div>
      )}
    </div>
  );

  const renderPosts = () => (
    <div className="card">
      <div className="section-header">
        <h2>Посты</h2>
        <button className="icon-btn" onClick={loadPosts} disabled={postsLoading}>
          <RefreshCw size={18} />
        </button>
      </div>
      {postsLoading ? (
        <div className="loader">
          <Loader2 className="spin" size={32} />
        </div>
      ) : (
        <div className="list">
          {postsData.posts.map((post) => (
            <div key={post.id} className="list-item">
              <div className="list-item-main">
                <div className="list-item-title">
                  Автор: @{post.author?.username || 'Удалён'} — {formatDate(post.createdAt)}
                </div>
                <div className="post-content-preview">{post.content || 'Без текста'}</div>
                <div className="list-item-meta">
                  <span>Лайки: {post.likesCount}</span>
                  <span>Комментарии: {post.commentsCount}</span>
                  {post.isNSFW && <span className="badge badge-warning">NSFW</span>}
                </div>
                {post.images?.length ? (
                  <div className="image-grid">
                    {post.images.map((img, idx) => (
                      <div key={idx} className="image-thumb">
                        <img src={img} alt="" />
                        <button className="image-remove" onClick={() => handleRemoveImage(post.id, idx)}>
                          <Trash2 size={16} />
                        </button>
                      </div>
                    ))}
                  </div>
                ) : null}
              </div>
              <div className="list-item-actions">
                <button className="btn" onClick={() => handlePostEdit(post)}>
                  <Edit size={16} />
                  Редактировать
                </button>
                <button className="btn danger" onClick={() => handlePostDelete(post.id)}>
                  <Trash2 size={16} />
                  Удалить
                </button>
                <button className="btn warn" onClick={() => handleBanAuthor(post.id)}>
                  <Ban size={16} />
                  Бан автора
                </button>
              </div>
            </div>
          ))}
        </div>
      )}
    </div>
  );

  const renderReports = () => (
    <div className="card">
      <div className="section-header">
        <h2>Репорты</h2>
        <button className="icon-btn" onClick={loadReports} disabled={reportsLoading}>
          <RefreshCw size={18} />
        </button>
      </div>
      {reportsLoading ? (
        <div className="loader">
          <Loader2 className="spin" size={32} />
        </div>
      ) : (
        <div className="list">
          {reportsData.reports.map((report) => (
            <div key={report.id} className="list-item">
              <div className="list-item-main">
                <div className="list-item-title">
                  Репорт от @{report.reporter?.username || 'Unknown'} — {formatDate(report.createdAt)}
                </div>
                <div className="list-item-subtitle">Статус: {report.status}</div>
                <div className="report-content">
                  <p>{report.reason || 'Причина не указана'}</p>
                  {report.post && (
                    <div className="report-post">
                      <strong>Пост:</strong> {report.post.content || 'Без текста'}
                    </div>
                  )}
                </div>
              </div>
              <div className="list-item-actions">
                <button className="btn" onClick={() => handleReportStatus(report.id, 'resolved')}>
                  Решено
                </button>
                <button className="btn warn" onClick={() => handleReportStatus(report.id, 'dismissed')}>
                  Отклонить
                </button>
              </div>
            </div>
          ))}
        </div>
      )}
    </div>
  );

  const renderChat = () => (
    <div className="card chat-card">
      <div className="section-header">
        <h2>Лайвчат админов</h2>
        {chatState.connected ? (
          <span className="badge badge-success">В сети</span>
        ) : (
          <span className="badge badge-warning">Подключение...</span>
        )}
      </div>
      <div className="chat-online">
        Онлайн:{' '}
        {chatState.online.length
          ? chatState.online.map((admin) => `@${admin.username}`).join(', ')
          : '—'}
      </div>
      <div className="chat-list" ref={chatListRef}>
        {chatState.messages.map((message) => (
          <div
            key={message.id}
            className={classNames(
              'chat-message',
              message.username === user.username && 'chat-message-own'
            )}
          >
            <div className="chat-message-author">@{message.username}</div>
            <div className="chat-message-text">{message.text}</div>
            <div className="chat-message-time">{formatDate(message.createdAt)}</div>
          </div>
        ))}
      </div>
      <div className="chat-input">
        <input
          type="text"
          value={chatInput}
          onChange={(e) => setChatInput(e.target.value)}
          placeholder="Сообщение для админов..."
        />
        <button className="btn" onClick={handleSendChat} disabled={!chatState.connected}>
          <SendHorizontal size={18} />
        </button>
      </div>
    </div>
  );

  const renderPublish = () => (
    <div className="card">
      <div className="section-header">
        <h2>Публикация в @reichenbfurry</h2>
      </div>
      <div className="publish-form">
        <label>
          Описание
          <textarea
            value={publishState.description}
            onChange={(e) =>
              setPublishState((prev) => ({ ...prev, description: e.target.value }))
            }
            maxLength={1024}
            placeholder="Текст поста"
          />
        </label>
        <label>
          Теги (через пробел или запятую)
          <input
            type="text"
            value={publishState.tags}
            onChange={(e) => setPublishState((prev) => ({ ...prev, tags: e.target.value }))}
            placeholder="#furry #art"
          />
        </label>
        <label>
          Номер администратора (#a1 - #a10)
          <select
            value={publishState.slot}
            onChange={(e) =>
              setPublishState((prev) => ({ ...prev, slot: parseInt(e.target.value, 10) }))
            }
          >
            {slotOptions.map((option) => (
              <option key={option} value={option}>
                #{`a${option}`}
              </option>
            ))}
          </select>
        </label>
        <label>
          Медиа (до 10, фото или видео)
          <input type="file" accept="image/*,video/*" multiple onChange={handleFileChange} />
        </label>
        {publishState.files.length > 0 && (
          <div className="file-list">
            {publishState.files.map((file, index) => (
              <div key={index} className="file-item">
                {file.name} ({Math.round(file.size / 1024)} KB)
              </div>
            ))}
          </div>
        )}
        <button className="btn primary" disabled={publishing} onClick={handlePublish}>
          {publishing ? <Loader2 className="spin" size={18} /> : <SendHorizontal size={18} />}
          Опубликовать
        </button>
      </div>
    </div>
  );

  const renderContent = () => {
    switch (tab) {
      case 'users':
        return renderUsers();
      case 'posts':
        return renderPosts();
      case 'reports':
        return renderReports();
      case 'chat':
        return renderChat();
      case 'publish':
        return renderPublish();
      default:
        return null;
    }
  };

  if (loading) {
    return (
      <div className="fullscreen-center">
        <Loader2 className="spin" size={48} />
        <p>Загрузка модераторского интерфейса...</p>
      </div>
    );
  }

  if (error) {
    return (
      <div className="fullscreen-center">
        <ShieldCheck size={48} />
        <p>{error}</p>
      </div>
    );
  }

  return (
    <div className="app-container">
      <header className="app-header">
        <div>
          <h1>Nakama Moderation</h1>
          <span className="subtitle">@{user.username}</span>
        </div>
        <div className="header-actions">
          <button className="btn" onClick={() => window.Telegram?.WebApp?.close()}>
            Закрыть
          </button>
        </div>
      </header>

      <nav className="tabbar">
        {TABS.map((item) => {
          const Icon = item.icon;
          return (
            <button
              key={item.id}
              className={classNames('tab-btn', tab === item.id && 'tab-btn-active')}
              onClick={() => setTab(item.id)}
            >
              <Icon size={18} />
              <span>{item.title}</span>
            </button>
          );
        })}
      </nav>

      <main className="content">{renderContent()}</main>
    </div>
  );
}

