/*
Copyright (C) 2025 QuantumNous

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.

For commercial licensing, please contact support@quantumnous.com
*/

import React, { useState, useEffect, useRef } from 'react';
import {
  Modal,
  Button,
  Typography,
  Select,
  Input,
  Space,
  Spin,
  Card,
  Tag,
  Empty,
  Switch,
  Divider,
  Tooltip,
  Radio,
} from '@douyinfe/semi-ui';
import {
  FaCopy,
  FaSearch,
  FaClock,
  FaTerminal,
  FaServer,
  FaInfoCircle,
  FaLink,
} from 'react-icons/fa';
import { IconRefresh, IconDownload } from '@douyinfe/semi-icons';
import { API, showError, showSuccess, copy, timestamp2string } from '../../../../helpers';

const { Text } = Typography;

const ALL_CONTAINERS = '__all__';

const ViewLogsModal = ({ 
  visible, 
  onCancel, 
  deployment, 
  t 
}) => {
  const [logLines, setLogLines] = useState([]);
  const [loading, setLoading] = useState(false);
  const [autoRefresh, setAutoRefresh] = useState(false);
  const [searchTerm, setSearchTerm] = useState('');
  const [following, setFollowing] = useState(false);
  const [containers, setContainers] = useState([]);
  const [containersLoading, setContainersLoading] = useState(false);
  const [selectedContainerId, setSelectedContainerId] = useState(ALL_CONTAINERS);
  const [containerDetails, setContainerDetails] = useState(null);
  const [containerDetailsLoading, setContainerDetailsLoading] = useState(false);
  const [streamFilter, setStreamFilter] = useState('stdout');
  const [lastUpdatedAt, setLastUpdatedAt] = useState(null);
  
  const logContainerRef = useRef(null);
  const autoRefreshRef = useRef(null);

  // Auto scroll to bottom when new logs arrive
  const scrollToBottom = () => {
    if (logContainerRef.current) {
      logContainerRef.current.scrollTop = logContainerRef.current.scrollHeight;
    }
  };

  const resolveStreamValue = (value) => {
    if (typeof value === 'string') {
      return value;
    }
    if (value && typeof value.value === 'string') {
      return value.value;
    }
    if (value && value.target && typeof value.target.value === 'string') {
      return value.target.value;
    }
    return '';
  };

  const handleStreamChange = (value) => {
    const next = resolveStreamValue(value) || 'stdout';
    setStreamFilter(next);
  };

  const fetchLogs = async (containerIdOverride = undefined) => {
    if (!deployment?.id) return;

    const containerId = typeof containerIdOverride === 'string' ? containerIdOverride : selectedContainerId;

    if (!containerId || containerId === ALL_CONTAINERS) {
      setLogLines([]);
      setLastUpdatedAt(null);
      setLoading(false);
      return;
    }

    setLoading(true);
    try {
      const params = new URLSearchParams();
      params.append('container_id', containerId);

      const streamValue = resolveStreamValue(streamFilter) || 'stdout';
      if (streamValue && streamValue !== 'all') {
        params.append('stream', streamValue);
      }
      if (following) params.append('follow', 'true');

      const response = await API.get(`/api/deployments/${deployment.id}/logs?${params}`);

      if (response.data.success) {
        const rawContent = typeof response.data.data === 'string' ? response.data.data : '';
        const normalized = rawContent.replace(/\r\n?/g, '\n');
        const lines = normalized ? normalized.split('\n') : [];

        setLogLines(lines);
        setLastUpdatedAt(new Date());

        setTimeout(scrollToBottom, 100);
      }
    } catch (error) {
      showError(t('获取日志失败') + ': ' + (error.response?.data?.message || error.message));
    } finally {
      setLoading(false);
    }
  };

  const fetchContainers = async () => {
    if (!deployment?.id) return;

    setContainersLoading(true);
    try {
      const response = await API.get(`/api/deployments/${deployment.id}/containers`);

      if (response.data.success) {
        const list = response.data.data?.containers || [];
        setContainers(list);

        setSelectedContainerId((current) => {
          if (current !== ALL_CONTAINERS && list.some(item => item.container_id === current)) {
            return current;
          }

          return list.length > 0 ? list[0].container_id : ALL_CONTAINERS;
        });

        if (list.length === 0) {
          setContainerDetails(null);
        }
      }
    } catch (error) {
      showError(t('获取容器列表失败') + ': ' + (error.response?.data?.message || error.message));
    } finally {
      setContainersLoading(false);
    }
  };

  const fetchContainerDetails = async (containerId) => {
    if (!deployment?.id || !containerId || containerId === ALL_CONTAINERS) {
      setContainerDetails(null);
      return;
    }

    setContainerDetailsLoading(true);
    try {
      const response = await API.get(`/api/deployments/${deployment.id}/containers/${containerId}`);

      if (response.data.success) {
        setContainerDetails(response.data.data || null);
      }
    } catch (error) {
      showError(t('获取容器详情失败') + ': ' + (error.response?.data?.message || error.message));
    } finally {
      setContainerDetailsLoading(false);
    }
  };

  const handleContainerChange = (value) => {
    const newValue = value || ALL_CONTAINERS;
    setSelectedContainerId(newValue);
    setLogLines([]);
    setLastUpdatedAt(null);
  };

  const refreshContainerDetails = () => {
    if (selectedContainerId && selectedContainerId !== ALL_CONTAINERS) {
      fetchContainerDetails(selectedContainerId);
    }
  };

  const renderContainerStatusTag = (status) => {
    if (!status) {
      return (
        <Tag color="grey" size="small">
          {t('未知状态')}
        </Tag>
      );
    }

    const normalized = typeof status === 'string' ? status.trim().toLowerCase() : '';
    const statusMap = {
      running: { color: 'green', label: '运行中' },
      pending: { color: 'orange', label: '准备中' },
      deployed: { color: 'blue', label: '已部署' },
      failed: { color: 'red', label: '失败' },
      destroyed: { color: 'red', label: '已销毁' },
      stopping: { color: 'orange', label: '停止中' },
      terminated: { color: 'grey', label: '已终止' },
    };

    const config = statusMap[normalized] || { color: 'grey', label: status };

    return (
      <Tag color={config.color} size="small">
        {t(config.label)}
      </Tag>
    );
  };

  const currentContainer = selectedContainerId !== ALL_CONTAINERS
    ? containers.find((ctr) => ctr.container_id === selectedContainerId)
    : null;

  const refreshLogs = () => {
    if (selectedContainerId && selectedContainerId !== ALL_CONTAINERS) {
      fetchContainerDetails(selectedContainerId);
    }
    fetchLogs();
  };

  const downloadLogs = () => {
    const sourceLogs = filteredLogs.length > 0 ? filteredLogs : logLines;
    if (sourceLogs.length === 0) {
      showError(t('暂无日志可下载'));
      return;
    }
    const logText = sourceLogs.join('\n');

    const blob = new Blob([logText], { type: 'text/plain' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    const safeContainerId = selectedContainerId && selectedContainerId !== ALL_CONTAINERS
      ? selectedContainerId.replace(/[^a-zA-Z0-9_-]/g, '-')
      : '';
    const fileName = safeContainerId
      ? `deployment-${deployment.id}-container-${safeContainerId}-logs.txt`
      : `deployment-${deployment.id}-logs.txt`;
    a.download = fileName;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);
    
    showSuccess(t('日志已下载'));
  };

  const copyAllLogs = async () => {
    const sourceLogs = filteredLogs.length > 0 ? filteredLogs : logLines;
    if (sourceLogs.length === 0) {
      showError(t('暂无日志可复制'));
      return;
    }
    const logText = sourceLogs.join('\n');

    const copied = await copy(logText);
    if (copied) {
      showSuccess(t('日志已复制到剪贴板'));
    } else {
      showError(t('复制失败，请手动选择文本复制'));
    }
  };

  // Auto refresh functionality
  useEffect(() => {
    if (autoRefresh && visible) {
      autoRefreshRef.current = setInterval(() => {
        fetchLogs();
      }, 5000);
    } else {
      if (autoRefreshRef.current) {
        clearInterval(autoRefreshRef.current);
        autoRefreshRef.current = null;
      }
    }

    return () => {
      if (autoRefreshRef.current) {
        clearInterval(autoRefreshRef.current);
      }
    };
  }, [autoRefresh, visible, selectedContainerId, streamFilter, following]);

  useEffect(() => {
    if (visible && deployment?.id) {
      fetchContainers();
    } else if (!visible) {
      setContainers([]);
      setSelectedContainerId(ALL_CONTAINERS);
      setContainerDetails(null);
      setStreamFilter('stdout');
      setLogLines([]);
      setLastUpdatedAt(null);
    }
  }, [visible, deployment?.id]);

  useEffect(() => {
    if (visible) {
      setStreamFilter('stdout');
    }
  }, [selectedContainerId, visible]);

  useEffect(() => {
    if (visible && deployment?.id) {
      fetchContainerDetails(selectedContainerId);
    }
  }, [visible, deployment?.id, selectedContainerId]);

  // Initial load and cleanup
  useEffect(() => {
    if (visible && deployment?.id) {
      fetchLogs();
    }

    return () => {
      if (autoRefreshRef.current) {
        clearInterval(autoRefreshRef.current);
      }
    };
  }, [visible, deployment?.id, streamFilter, selectedContainerId, following]);

  // Filter logs based on search term
  const filteredLogs = logLines
    .map((line) => line ?? '')
    .filter((line) =>
      !searchTerm || line.toLowerCase().includes(searchTerm.toLowerCase()),
    );

  const renderLogEntry = (line, index) => (
    <div
      key={`${index}-${line.slice(0, 20)}`}
      className="py-1 px-3 hover:bg-gray-50 font-mono text-sm border-b border-gray-100 whitespace-pre-wrap break-words"
    >
      {line}
    </div>
  );

  return (
    <Modal
      title={
        <div className="flex items-center gap-2">
          <FaTerminal className="text-blue-500" />
          <span>{t('容器日志')}</span>
          <Text type="secondary" size="small">
            - {deployment?.container_name || deployment?.id}
          </Text>
        </div>
      }
      visible={visible}
      onCancel={onCancel}
      footer={null}
      width={1000}
      height={700}
      className="logs-modal"
      style={{ top: 20 }}
    >
      <div className="flex flex-col h-full max-h-[600px]">
        {/* Controls */}
        <Card className="mb-4 border-0 shadow-sm">
          <div className="flex items-center justify-between flex-wrap gap-3">
            <Space wrap>
              <Select
                prefix={<FaServer />}
                placeholder={t('选择容器')}
                value={selectedContainerId}
                onChange={handleContainerChange}
                style={{ width: 240 }}
                size="small"
                loading={containersLoading}
                dropdownStyle={{ maxHeight: 320, overflowY: 'auto' }}
              >
                <Select.Option value={ALL_CONTAINERS}>
                  {t('全部容器')}
                </Select.Option>
                {containers.map((ctr) => (
                  <Select.Option key={ctr.container_id} value={ctr.container_id}>
                    <div className="flex flex-col">
                      <span className="font-mono text-xs">{ctr.container_id}</span>
                      <span className="text-xs text-gray-500">
                        {ctr.brand_name || 'IO.NET'}
                        {ctr.hardware ? ` · ${ctr.hardware}` : ''}
                      </span>
                    </div>
                  </Select.Option>
                ))}
              </Select>

              <Input
                prefix={<FaSearch />}
                placeholder={t('搜索日志内容')}
                value={searchTerm}
                onChange={setSearchTerm}
                style={{ width: 200 }}
                size="small"
              />
              
              <Space align="center" className="ml-2">
                <Text size="small" type="secondary">
                  {t('日志流')}
                </Text>
                <Radio.Group
                  type="button"
                  size="small"
                  value={streamFilter}
                  onChange={handleStreamChange}
                >
                  <Radio value="stdout">STDOUT</Radio>
                  <Radio value="stderr">STDERR</Radio>
                </Radio.Group>
              </Space>

              <div className="flex items-center gap-2">
                <Switch
                  checked={autoRefresh}
                  onChange={setAutoRefresh}
                  size="small"
                />
                <Text size="small">{t('自动刷新')}</Text>
              </div>

              <div className="flex items-center gap-2">
                <Switch
                  checked={following}
                  onChange={setFollowing}
                  size="small"
                />
                <Text size="small">{t('跟随日志')}</Text>
              </div>
            </Space>

            <Space>
              <Tooltip content={t('刷新日志')}>
                <Button 
                  icon={<IconRefresh />} 
                  onClick={refreshLogs}
                  loading={loading}
                  size="small"
                  theme="borderless"
                />
              </Tooltip>
              
              <Tooltip content={t('复制日志')}>
                <Button 
                  icon={<FaCopy />} 
                  onClick={copyAllLogs}
                  size="small"
                  theme="borderless"
                  disabled={logLines.length === 0}
                />
              </Tooltip>
              
              <Tooltip content={t('下载日志')}>
                <Button 
                  icon={<IconDownload />} 
                  onClick={downloadLogs}
                  size="small"
                  theme="borderless"
                  disabled={logLines.length === 0}
                />
              </Tooltip>
            </Space>
          </div>
          
          {/* Status Info */}
          <Divider margin="12px" />
          <div className="flex items-center justify-between">
            <Space size="large">
              <Text size="small" type="secondary">
                {t('共 {{count}} 条日志', { count: logLines.length })}
              </Text>
              {searchTerm && (
                <Text size="small" type="secondary">
                  {t('(筛选后显示 {{count}} 条)', { count: filteredLogs.length })}
                </Text>
              )}
              {autoRefresh && (
                <Tag color="green" size="small">
                  <FaClock className="mr-1" />
                  {t('自动刷新中')}
                </Tag>
              )}
            </Space>
            
            <Text size="small" type="secondary">
              {t('状态')}: {deployment?.status || 'unknown'}
            </Text>
          </div>

          {selectedContainerId !== ALL_CONTAINERS && (
            <>
              <Divider margin="12px" />
              <div className="flex flex-col gap-3">
                <div className="flex items-center justify-between flex-wrap gap-2">
                  <Space>
                    <Tag color="blue" size="small">
                      {t('容器')}
                    </Tag>
                    <Text className="font-mono text-xs">
                      {selectedContainerId}
                    </Text>
                    {renderContainerStatusTag(containerDetails?.status || currentContainer?.status)}
                  </Space>

                  <Space>
                    {containerDetails?.public_url && (
                      <Tooltip content={containerDetails.public_url}>
                        <Button
                          icon={<FaLink />}
                          size="small"
                          theme="borderless"
                          onClick={() => window.open(containerDetails.public_url, '_blank')}
                        />
                      </Tooltip>
                    )}
                    <Tooltip content={t('刷新容器信息')}>
                      <Button
                        icon={<IconRefresh />}
                        onClick={refreshContainerDetails}
                        size="small"
                        theme="borderless"
                        loading={containerDetailsLoading}
                      />
                    </Tooltip>
                  </Space>
                </div>

                {containerDetailsLoading ? (
                  <div className="flex items-center justify-center py-6">
                    <Spin tip={t('加载容器详情中...')} />
                  </div>
                ) : containerDetails ? (
                  <div className="grid gap-4 md:grid-cols-2 text-sm">
                    <div className="flex items-center gap-2">
                      <FaInfoCircle className="text-blue-500" />
                      <Text type="secondary">{t('硬件')}</Text>
                      <Text>
                        {containerDetails?.brand_name || currentContainer?.brand_name || t('未知品牌')}
                        {(containerDetails?.hardware || currentContainer?.hardware) ? ` · ${containerDetails?.hardware || currentContainer?.hardware}` : ''}
                      </Text>
                    </div>
                    <div className="flex items-center gap-2">
                      <FaServer className="text-purple-500" />
                      <Text type="secondary">{t('GPU/容器')}</Text>
                      <Text>{containerDetails?.gpus_per_container ?? currentContainer?.gpus_per_container ?? 0}</Text>
                    </div>
                    <div className="flex items-center gap-2">
                      <FaClock className="text-orange-500" />
                      <Text type="secondary">{t('创建时间')}</Text>
                      <Text>
                        {containerDetails?.created_at
                          ? timestamp2string(containerDetails.created_at)
                          : currentContainer?.created_at
                            ? timestamp2string(currentContainer.created_at)
                            : t('未知')}
                      </Text>
                    </div>
                    <div className="flex items-center gap-2">
                      <FaInfoCircle className="text-green-500" />
                      <Text type="secondary">{t('运行时长')}</Text>
                      <Text>{containerDetails?.uptime_percent ?? currentContainer?.uptime_percent ?? 0}%</Text>
                    </div>
                  </div>
                ) : (
                  <Text size="small" type="secondary">
                    {t('暂无容器详情')}
                  </Text>
                )}

                {containerDetails?.events && containerDetails.events.length > 0 && (
                  <div className="bg-gray-50 rounded-lg p-3">
                    <Text size="small" type="secondary">
                      {t('最近事件')}
                    </Text>
                    <div className="mt-2 space-y-2 max-h-32 overflow-y-auto">
                      {containerDetails.events.slice(0, 5).map((event, index) => (
                        <div key={`${event.time}-${index}`} className="flex gap-3 text-xs font-mono">
                          <span className="text-gray-500">
                            {event.time ? timestamp2string(event.time) : '--'}
                          </span>
                          <span className="text-gray-700 break-all flex-1">
                            {event.message}
                          </span>
                        </div>
                      ))}
                    </div>
                  </div>
                )}
              </div>
            </>
          )}
        </Card>

        {/* Log Content */}
        <div className="flex-1 flex flex-col border rounded-lg bg-gray-50 overflow-hidden">
          <div 
            ref={logContainerRef}
            className="flex-1 overflow-y-auto bg-white"
            style={{ maxHeight: '400px' }}
          >
            {loading && logLines.length === 0 ? (
              <div className="flex items-center justify-center p-8">
                <Spin tip={t('加载日志中...')} />
              </div>
            ) : filteredLogs.length === 0 ? (
              <Empty
                image={Empty.PRESENTED_IMAGE_SIMPLE}
                description={
                  searchTerm ? t('没有匹配的日志条目') : t('暂无日志')
                }
                style={{ padding: '60px 20px' }}
              />
            ) : (
              <div>
                {filteredLogs.map((log, index) => renderLogEntry(log, index))}
              </div>
            )}
          </div>
          
          {/* Footer status */}
          {logLines.length > 0 && (
            <div className="flex items-center justify-between px-3 py-2 bg-gray-50 border-t text-xs text-gray-500">
              <span>
                {following ? t('正在跟随最新日志') : t('日志已加载')}
              </span>
              <span>
                {t('最后更新')}: {lastUpdatedAt ? lastUpdatedAt.toLocaleTimeString() : '--'}
              </span>
            </div>
          )}
        </div>
      </div>
    </Modal>
  );
};

export default ViewLogsModal;
