import { useState, useEffect, useCallback, useRef } from 'react';
import { Row, Col, List, Card, Input, Button, Tag, Badge, Space, Typography, Empty, Spin, App, Checkbox, Select, Collapse } from 'antd';
import { SendOutlined, CheckOutlined, ReadOutlined, CloseCircleOutlined, LinkOutlined, PlusOutlined } from '@ant-design/icons';
import { api } from '@/lib/api';
import type { SmsConversation, SmsPaginatedResponse } from '@/types/sms';
import type { AppOutletContext } from '@/types/api';
import { useOutletContext, Link } from 'react-router-dom';
import NewConversationModal from './NewConversationModal';

const { Text, Paragraph } = Typography;
const { Search, TextArea } = Input;

const RESPONSE_TYPE_COLORS: Record<string, string> = {
  POSITIVE: 'success',
  NEGATIVE: 'error',
  QUESTION: 'processing',
  OPT_OUT: 'volcano',
  NEUTRAL: 'default',
};

export default function SmsConversationsPage() {
  const { setPageHeader } = useOutletContext<AppOutletContext>();
  const { message } = App.useApp();

  const [conversations, setConversations] = useState<SmsConversation[]>([]);
  const [total, setTotal] = useState(0);
  const [loading, setLoading] = useState(true);
  const [search, setSearch] = useState('');
  const [selected, setSelected] = useState<SmsConversation | null>(null);
  const [detailLoading, setDetailLoading] = useState(false);
  const [replyText, setReplyText] = useState('');
  const [sending, setSending] = useState(false);
  const messagesEndRef = useRef<HTMLDivElement>(null);

  // Notes & tags state
  const [notes, setNotes] = useState('');
  const [tags, setTags] = useState<string[]>([]);
  const [notesSaving, setNotesSaving] = useState(false);
  const [tagsSaving, setTagsSaving] = useState(false);

  // New conversation modal
  const [newConvOpen, setNewConvOpen] = useState(false);

  // Bulk selection state
  const [selectedIds, setSelectedIds] = useState<Set<string>>(new Set());
  const [bulkLoading, setBulkLoading] = useState(false);

  useEffect(() => {
    setPageHeader({ title: 'SMS Conversations', subtitle: 'View and reply to SMS threads' });
  }, [setPageHeader]);

  const fetchConversations = useCallback(async (s?: string) => {
    setLoading(true);
    try {
      const { data } = await api.get<SmsPaginatedResponse<SmsConversation>>('/sms/conversations', {
        params: { limit: 100, search: s || search || undefined },
      });
      setConversations(data.items);
      setTotal(data.total);
    } finally {
      setLoading(false);
    }
  }, [search]);

  useEffect(() => { fetchConversations(); }, [fetchConversations]);

  // Auto-refresh
  useEffect(() => {
    const interval = setInterval(() => fetchConversations(), 10000);
    return () => clearInterval(interval);
  }, [fetchConversations]);

  const selectConversation = async (conv: SmsConversation) => {
    setDetailLoading(true);
    try {
      const { data } = await api.get<SmsConversation>(`/sms/conversations/${conv.id}`);
      setSelected(data);
      setNotes(data.notes || '');
      setTags(data.tags || []);
      // Mark as read
      if (conv.unreadCount > 0) {
        api.post(`/sms/conversations/${conv.id}/read`).catch(() => {});
        fetchConversations();
      }
    } finally {
      setDetailLoading(false);
    }
    // Scroll to bottom
    setTimeout(() => messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' }), 100);
  };

  const handleReply = async () => {
    if (!selected || !replyText.trim()) return;
    setSending(true);
    try {
      await api.post(`/sms/conversations/${selected.id}/reply`, { message: replyText.trim() });
      message.success('Reply queued');
      setReplyText('');
      selectConversation(selected);
    } catch {
      message.error('Failed to send reply');
    } finally {
      setSending(false);
    }
  };

  const handleNotesSave = async () => {
    if (!selected) return;
    setNotesSaving(true);
    try {
      await api.put(`/sms/conversations/${selected.id}/notes`, { notes });
    } catch {
      message.error('Failed to save notes');
    } finally {
      setNotesSaving(false);
    }
  };

  const handleTagsChange = async (newTags: string[]) => {
    setTags(newTags);
    if (!selected) return;
    setTagsSaving(true);
    try {
      await api.put(`/sms/conversations/${selected.id}/tags`, { tags: newTags });
    } catch {
      message.error('Failed to save tags');
    } finally {
      setTagsSaving(false);
    }
  };

  // Bulk actions
  const toggleSelection = (id: string) => {
    setSelectedIds((prev) => {
      const next = new Set(prev);
      if (next.has(id)) next.delete(id);
      else next.add(id);
      return next;
    });
  };

  const toggleSelectAll = () => {
    if (selectedIds.size === conversations.length) {
      setSelectedIds(new Set());
    } else {
      setSelectedIds(new Set(conversations.map((c) => c.id)));
    }
  };

  const handleBulkRead = async () => {
    const ids = Array.from(selectedIds);
    if (ids.length === 0) return;
    setBulkLoading(true);
    try {
      const { data } = await api.post('/sms/conversations/bulk-read', { ids });
      message.success(`Marked ${data.updated} conversation${data.updated !== 1 ? 's' : ''} as read`);
      setSelectedIds(new Set());
      fetchConversations();
    } catch {
      message.error('Failed to mark as read');
    } finally {
      setBulkLoading(false);
    }
  };

  const handleBulkClose = async () => {
    const ids = Array.from(selectedIds);
    if (ids.length === 0) return;
    setBulkLoading(true);
    try {
      const { data } = await api.post('/sms/conversations/bulk-close', { ids });
      message.success(`Closed ${data.updated} conversation${data.updated !== 1 ? 's' : ''}`);
      setSelectedIds(new Set());
      fetchConversations();
    } catch {
      message.error('Failed to close conversations');
    } finally {
      setBulkLoading(false);
    }
  };

  return (
    <Row gutter={16} style={{ height: 'calc(100vh - 200px)', minHeight: 400 }}>
      {/* Conversation List (left panel) */}
      <Col xs={24} md={8} style={{ height: '100%', display: 'flex', flexDirection: 'column' }}>
        <div style={{ display: 'flex', gap: 8, marginBottom: 8 }}>
          <Search
            placeholder="Search by phone or name..."
            onSearch={(v) => { setSearch(v); fetchConversations(v); }}
            allowClear
            style={{ flex: 1 }}
          />
          <Button type="primary" icon={<PlusOutlined />} onClick={() => setNewConvOpen(true)}>
            New
          </Button>
        </div>

        {/* Bulk action bar */}
        {selectedIds.size > 0 && (
          <Space style={{ marginBottom: 8, padding: '4px 8px', background: 'rgba(255,255,255,0.04)', borderRadius: 6 }}>
            <Text type="secondary" style={{ fontSize: 12 }}>{selectedIds.size} selected</Text>
            <Button size="small" icon={<ReadOutlined />} onClick={handleBulkRead} loading={bulkLoading}>Mark Read</Button>
            <Button size="small" icon={<CloseCircleOutlined />} onClick={handleBulkClose} loading={bulkLoading}>Close</Button>
            <Button size="small" type="text" onClick={() => setSelectedIds(new Set())}>Clear</Button>
          </Space>
        )}

        <div style={{ flex: 1, overflowY: 'auto' }}>
          {conversations.length > 0 && (
            <div style={{ padding: '4px 12px', marginBottom: 4 }}>
              <Checkbox
                checked={selectedIds.size === conversations.length && conversations.length > 0}
                indeterminate={selectedIds.size > 0 && selectedIds.size < conversations.length}
                onChange={toggleSelectAll}
              >
                <Text type="secondary" style={{ fontSize: 12 }}>Select all</Text>
              </Checkbox>
            </div>
          )}
          <List
            loading={loading}
            dataSource={conversations}
            locale={{ emptyText: <Empty description="No conversations yet" /> }}
            renderItem={(conv) => (
              <List.Item
                style={{
                  cursor: 'pointer',
                  background: selected?.id === conv.id ? 'rgba(255,255,255,0.06)' : undefined,
                  padding: '8px 12px',
                  borderRadius: 6,
                }}
              >
                <div style={{ display: 'flex', alignItems: 'flex-start', width: '100%', gap: 8 }}>
                  <Checkbox
                    checked={selectedIds.has(conv.id)}
                    onClick={(e) => e.stopPropagation()}
                    onChange={() => toggleSelection(conv.id)}
                    style={{ marginTop: 4 }}
                  />
                  <div style={{ flex: 1 }} onClick={() => selectConversation(conv)}>
                    <Space>
                      <Badge count={conv.unreadCount} size="small">
                        <Text strong>{conv.contactName || conv.phone}</Text>
                      </Badge>
                      {conv.status === 'OPTED_OUT' && <Tag color="volcano" style={{ fontSize: 10 }}>OPT OUT</Tag>}
                      {conv.status === 'CLOSED' && <Tag color="default" style={{ fontSize: 10 }}>CLOSED</Tag>}
                    </Space>
                    <Space direction="vertical" size={0}>
                      {conv.contactName && <Text type="secondary" style={{ fontSize: 12 }}>{conv.phone}</Text>}
                      {conv.campaign && <Text type="secondary" style={{ fontSize: 11 }}>{conv.campaign.name}</Text>}
                      {conv.lastMessageAt && (
                        <Text type="secondary" style={{ fontSize: 11 }}>
                          {new Date(conv.lastMessageAt).toLocaleString()}
                        </Text>
                      )}
                    </Space>
                  </div>
                </div>
              </List.Item>
            )}
          />
          <Text type="secondary" style={{ display: 'block', textAlign: 'center', marginTop: 8 }}>
            {total} conversation{total !== 1 ? 's' : ''}
          </Text>
        </div>
      </Col>

      {/* Message Thread (right panel) */}
      <Col xs={24} md={16} style={{ height: '100%', display: 'flex', flexDirection: 'column' }}>
        {!selected ? (
          <Card style={{ flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
            <Empty description="Select a conversation" />
          </Card>
        ) : (
          <Card
            title={
              <Space>
                <Text strong>{selected.contactName || selected.phone}</Text>
                {selected.campaign && <Tag>{selected.campaign.name}</Tag>}
                <Tag color={selected.status === 'ACTIVE' ? 'success' : selected.status === 'OPTED_OUT' ? 'volcano' : 'default'}>
                  {selected.status}
                </Tag>
                {selected.contact && (
                  <Link to={`/app/crm/contacts`} style={{ fontSize: 12 }}>
                    <LinkOutlined /> {selected.contact.displayName}
                  </Link>
                )}
              </Space>
            }
            style={{ flex: 1, display: 'flex', flexDirection: 'column' }}
            styles={{ body: { flex: 1, overflowY: 'auto', padding: '0' } }}
          >
            {detailLoading ? (
              <Spin style={{ display: 'block', margin: '40px auto' }} />
            ) : (
              <div style={{ display: 'flex', flexDirection: 'column', height: '100%' }}>
                {/* Notes & Tags collapsible section */}
                <Collapse
                  ghost
                  size="small"
                  style={{ borderBottom: '1px solid rgba(255,255,255,0.08)' }}
                  items={[{
                    key: 'meta',
                    label: <Text type="secondary" style={{ fontSize: 12 }}>Notes & Tags</Text>,
                    children: (
                      <Space direction="vertical" style={{ width: '100%' }} size={8}>
                        <div>
                          <Text type="secondary" style={{ fontSize: 11, display: 'block', marginBottom: 2 }}>Notes</Text>
                          <TextArea
                            rows={2}
                            value={notes}
                            onChange={(e) => setNotes(e.target.value)}
                            onBlur={handleNotesSave}
                            placeholder="Add notes about this conversation..."
                            style={{ fontSize: 12 }}
                          />
                          {notesSaving && <Text type="secondary" style={{ fontSize: 10 }}>Saving...</Text>}
                        </div>
                        <div>
                          <Text type="secondary" style={{ fontSize: 11, display: 'block', marginBottom: 2 }}>Tags</Text>
                          <Select
                            mode="tags"
                            style={{ width: '100%' }}
                            value={tags}
                            onChange={handleTagsChange}
                            placeholder="Add tags..."
                            tokenSeparators={[',']}
                            loading={tagsSaving}
                          />
                        </div>
                      </Space>
                    ),
                  }]}
                />

                {/* Messages */}
                <div style={{ flex: 1, overflowY: 'auto', padding: '12px 16px' }}>
                  {(selected.messages || []).map((msg) => (
                    <div
                      key={msg.id}
                      style={{
                        display: 'flex',
                        justifyContent: msg.direction === 'OUTBOUND' ? 'flex-end' : 'flex-start',
                        marginBottom: 8,
                      }}
                    >
                      <div
                        style={{
                          maxWidth: '70%',
                          padding: '8px 12px',
                          borderRadius: 12,
                          background: msg.direction === 'OUTBOUND'
                            ? 'rgba(157, 78, 221, 0.2)'
                            : 'rgba(255, 255, 255, 0.08)',
                        }}
                      >
                        <Paragraph style={{ margin: 0, whiteSpace: 'pre-wrap' }}>{msg.message}</Paragraph>
                        <Space size={4} style={{ marginTop: 2 }}>
                          <Text type="secondary" style={{ fontSize: 10 }}>
                            {new Date(msg.sentAt).toLocaleTimeString()}
                          </Text>
                          {msg.direction === 'OUTBOUND' && (
                            <Text type="secondary" style={{ fontSize: 10 }}>
                              {msg.status === 'SENT' ? <CheckOutlined style={{ color: '#52c41a' }} /> : msg.status}
                            </Text>
                          )}
                          {msg.direction === 'INBOUND' && msg.responseType && (
                            <Tag color={RESPONSE_TYPE_COLORS[msg.responseType]} style={{ fontSize: 10, lineHeight: '16px' }}>
                              {msg.responseType}
                            </Tag>
                          )}
                        </Space>
                      </div>
                    </div>
                  ))}
                  <div ref={messagesEndRef} />
                </div>

                {/* Reply composer */}
                {selected.status !== 'OPTED_OUT' && (
                  <div style={{ display: 'flex', gap: 8, padding: '12px 16px', borderTop: '1px solid rgba(255,255,255,0.08)' }}>
                    <Input
                      value={replyText}
                      onChange={(e) => setReplyText(e.target.value)}
                      placeholder="Type a reply..."
                      onPressEnter={handleReply}
                      disabled={sending}
                    />
                    <Button
                      type="primary"
                      icon={<SendOutlined />}
                      onClick={handleReply}
                      loading={sending}
                      disabled={!replyText.trim()}
                    />
                  </div>
                )}
                {selected.status === 'OPTED_OUT' && (
                  <Text type="warning" style={{ textAlign: 'center', padding: 12 }}>
                    This contact has opted out. Replies are disabled.
                  </Text>
                )}
              </div>
            )}
          </Card>
        )}
      </Col>

      <NewConversationModal
        open={newConvOpen}
        onClose={() => setNewConvOpen(false)}
        onCreated={(conv) => {
          fetchConversations();
          if (conv) setSelected(conv);
        }}
      />
    </Row>
  );
}
