import { useState, useEffect, useCallback, useRef } from 'react';
import { Button, Input, Spin, Popconfirm, message, Typography } from 'antd';
import { SendOutlined, CloseCircleOutlined, ArrowUpOutlined } from '@ant-design/icons';
import { useParams } from 'react-router-dom';
import { consultationApi, type Session, type Message } from '../../api/health/consultations';
import { StatusTag } from './components/StatusTag';
import { ImagePreview } from './components/ImagePreview';
import { useThemeMode } from '../../hooks/useThemeMode';
import { AuthButton } from '../../components/AuthButton';

const PAGE_SIZE = 30;
const POLL_INTERVAL = 10_000;

function formatTime(value: string): string {
  return new Date(value).toLocaleString('zh-CN', {
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit',
  });
}

/** Parse image URLs from message content (JSON array or single URL string). */
function parseImageUrls(content: string): string[] {
  try {
    const parsed = JSON.parse(content);
    if (Array.isArray(parsed)) return parsed.map(String);
    return [String(parsed)];
  } catch {
    return [content];
  }
}

const ROLE_ALIGN: Record<string, 'flex-start' | 'flex-end' | 'center'> = {
  patient: 'flex-start',
  doctor: 'flex-end',
  system: 'center',
};

export default function ConsultationDetail() {
  const { id } = useParams<{ id: string }>();
  const sessionId = id ?? '';

  // Session info
  const [session, setSession] = useState<Session | null>(null);
  const [sessionLoading, setSessionLoading] = useState(true);

  // Messages
  const [messages, setMessages] = useState<Message[]>([]);
  const [msgPage, setMsgPage] = useState(1);
  const [msgLoading, setMsgLoading] = useState(false);
  const [sending, setSending] = useState(false);
  const [inputText, setInputText] = useState('');
  const [hasMore, setHasMore] = useState(false);

  const chatEndRef = useRef<HTMLDivElement>(null);
  const shouldScrollRef = useRef(true);
  const pollRef = useRef<ReturnType<typeof setInterval> | null>(null);

  const isDark = useThemeMode();

  // --- Fetch session info ---
  const fetchSession = useCallback(async () => {
    if (!sessionId) return;
    setSessionLoading(true);
    try {
      const result = await consultationApi.getSession(sessionId);
      setSession(result);
    } catch {
      message.error('加载会话信息失败');
    }
    setSessionLoading(false);
  }, [sessionId]);

  // --- Fetch messages ---
  const fetchMessages = useCallback(
    async (page: number, append: boolean) => {
      if (!sessionId) return;
      setMsgLoading(true);
      try {
        const result = await consultationApi.listMessages(sessionId, {
          page,
          page_size: PAGE_SIZE,
        });
        const newMsgs = result.data;
        const totalPages = Math.ceil(result.total / PAGE_SIZE);

        if (append) {
          setMessages((prev) => [...newMsgs, ...prev]);
        } else {
          setMessages(newMsgs);
        }
        setHasMore(page < totalPages);
      } catch {
        message.error('加载消息失败');
      }
      setMsgLoading(false);
    },
    [sessionId],
  );

  // Initial load
  useEffect(() => {
    fetchSession();
    fetchMessages(1, false);
  }, [fetchSession, fetchMessages]);

  // Poll new messages while session is active
  useEffect(() => {
    if (!session || session.status === 'closed') return;

    const stopPolling = () => {
      if (pollRef.current) {
        clearInterval(pollRef.current);
        pollRef.current = null;
      }
    };

    stopPolling();
    pollRef.current = setInterval(async () => {
      if (!sessionId) return;
      try {
        const lastId = messages.length > 0 ? messages[messages.length - 1].id : undefined;
        const result = await consultationApi.listMessages(sessionId, {
          page: 1,
          page_size: 50,
          after_id: lastId,
        });
        if (result.data.length > 0) {
          setMessages((prev) => [...prev, ...result.data]);
          shouldScrollRef.current = true;
        }
      } catch {
        // silent
      }
    }, POLL_INTERVAL);

    return stopPolling;
  }, [session?.status, sessionId, messages.length]);

  // Auto-scroll to bottom on new messages
  useEffect(() => {
    if (shouldScrollRef.current && chatEndRef.current) {
      chatEndRef.current.scrollIntoView({ behavior: 'smooth' });
    }
  }, [messages.length]);

  // --- Send message ---
  const handleSend = async () => {
    const text = inputText.trim();
    if (!text || !sessionId) return;

    setSending(true);
    try {
      // Optimistically append to UI
      const optimisticMsg: Message = {
        id: `temp_${Date.now()}`,
        session_id: sessionId,
        sender_id: '',
        sender_role: 'doctor',
        content_type: 'text',
        content: text,
        is_read: false,
        created_at: new Date().toISOString(),
      };
      setMessages((prev) => [...prev, optimisticMsg]);
      setInputText('');
      shouldScrollRef.current = true;

      await consultationApi.createMessage({
        session_id: sessionId,
        sender_id: '',
        sender_role: 'doctor',
        content_type: 'text',
        content: text,
      });

      // Refresh to replace optimistic message with server version
      await fetchMessages(msgPage, false);
    } catch {
      message.error('发送失败');
    } finally {
      setSending(false);
    }
  };

  // --- Load more (older messages) ---
  const handleLoadMore = () => {
    const nextPage = msgPage + 1;
    setMsgPage(nextPage);
    shouldScrollRef.current = false;
    fetchMessages(nextPage, true);
  };

  // --- Close session ---
  const handleClose = async () => {
    if (!session) return;
    try {
      const updated = await consultationApi.closeSession(session.id, {
        version: session.version,
      });
      setSession(updated);
      message.success('会话已关闭');
    } catch {
      message.error('关闭会话失败');
    }
  };

  // --- Render a single message bubble ---
  const renderMessage = (msg: Message) => {
    const align = ROLE_ALIGN[msg.sender_role] ?? 'flex-start';

    // System messages: centered plain text
    if (msg.sender_role === 'system') {
      return (
        <div key={msg.id} style={{ textAlign: 'center', padding: '8px 0' }}>
          <Typography.Text type="secondary" style={{ fontSize: 12 }}>
            {msg.content}
          </Typography.Text>
        </div>
      );
    }

    const isImage = msg.content_type === 'image';

    return (
      <div
        key={msg.id}
        style={{
          display: 'flex',
          justifyContent: align,
          marginBottom: 12,
        }}
      >
        <div style={{ maxWidth: '70%' }}>
          {isImage ? (
            <ImagePreview urls={parseImageUrls(msg.content)} width={200} />
          ) : (
            <div
              style={{
                background: msg.sender_role === 'doctor' ? '#1890ff' : '#f0f0f0',
                color: msg.sender_role === 'doctor' ? '#fff' : '#000',
                padding: '8px 12px',
                borderRadius: 8,
                wordBreak: 'break-word',
              }}
            >
              <Typography.Paragraph style={{ margin: 0, color: 'inherit' }}>
                {msg.content}
              </Typography.Paragraph>
            </div>
          )}
          <Typography.Text type="secondary" style={{ fontSize: 11 }}>
            {formatTime(msg.created_at)}
          </Typography.Text>
        </div>
      </div>
    );
  };

  // --- Full render ---
  if (sessionLoading && messages.length === 0) {
    return (
      <div style={{ display: 'flex', justifyContent: 'center', padding: 100 }}>
        <Spin size="large" />
      </div>
    );
  }

  const isClosed = session?.status === 'closed';

  return (
    <div
      style={{
        display: 'flex',
        flexDirection: 'column',
        height: 'calc(100vh - 120px)',
        background: isDark ? '#111827' : '#FFFFFF',
        borderRadius: 12,
        border: `1px solid ${isDark ? '#0f172a' : '#f8fafc'}`,
        overflow: 'hidden',
      }}
    >
      {/* Top bar */}
      <div
        style={{
          display: 'flex',
          alignItems: 'center',
          gap: 12,
          padding: '12px 20px',
          borderBottom: `1px solid ${isDark ? '#1e293b' : '#f1f5f9'}`,
          flexShrink: 0,
        }}
      >
        <Typography.Text strong style={{ fontSize: 15 }}>
          咨询会话
        </Typography.Text>
        {session && (
          <>
            <Typography.Text type="secondary" style={{ fontSize: 13 }}>
              患者: {session.patient_id.slice(0, 8)}
            </Typography.Text>
            <Typography.Text type="secondary" style={{ fontSize: 13 }}>
              医护: {session.doctor_id ? session.doctor_id.slice(0, 8) : '-'}
            </Typography.Text>
            <StatusTag status={session.status} />
          </>
        )}
        {!session && (
          <Typography.Text type="secondary" style={{ fontSize: 13 }}>
            ID: {sessionId.slice(0, 8)}
          </Typography.Text>
        )}
        {session && !isClosed && (
          <AuthButton code="health.consultation.manage">
            <Popconfirm
              title="确认关闭该咨询会话？"
              onConfirm={handleClose}
              okText="确认"
              cancelText="取消"
            >
              <Button
                size="small"
                danger
                icon={<CloseCircleOutlined />}
                style={{ marginLeft: 'auto' }}
              >
                关闭会话
              </Button>
            </Popconfirm>
          </AuthButton>
        )}
      </div>

      {/* Chat area */}
      <div
        style={{
          flex: 1,
          overflow: 'auto',
          padding: '16px 20px',
          background: isDark ? '#0f172a' : '#f8fafc',
        }}
      >
        {hasMore && (
          <div style={{ textAlign: 'center', marginBottom: 16 }}>
            <Button
              size="small"
              icon={<ArrowUpOutlined />}
              loading={msgLoading}
              onClick={handleLoadMore}
            >
              加载更多
            </Button>
          </div>
        )}

        {msgLoading && messages.length === 0 && (
          <div style={{ textAlign: 'center', padding: 40 }}>
            <Spin />
          </div>
        )}

        {messages.map(renderMessage)}

        <div ref={chatEndRef} />
      </div>

      {/* Input area */}
      <div
        style={{
          display: 'flex',
          alignItems: 'flex-end',
          gap: 8,
          padding: '12px 20px',
          borderTop: `1px solid ${isDark ? '#1e293b' : '#f1f5f9'}`,
          flexShrink: 0,
          background: isDark ? '#111827' : '#FFFFFF',
        }}
      >
        <Input.TextArea
          value={inputText}
          onChange={(e) => setInputText(e.target.value)}
          placeholder={isClosed ? '会话已关闭' : '输入消息...'}
          autoSize={{ minRows: 1, maxRows: 4 }}
          style={{ flex: 1, borderRadius: 8 }}
          onPressEnter={(e) => {
            if (!e.shiftKey) {
              e.preventDefault();
              handleSend();
            }
          }}
          disabled={isClosed}
        />
        <Button
          type="primary"
          icon={<SendOutlined />}
          onClick={handleSend}
          loading={sending}
          disabled={!inputText.trim() || isClosed}
        >
          发送
        </Button>
      </div>
    </div>
  );
}
