import { useState, useEffect, useRef, useCallback } from 'react';
import { useParams } from 'react-router-dom';
import {
  Card, Typography, Tag, Radio, Button, Input, Space, Spin, Result,
  Divider, List, Form, Grid, App,
} from 'antd';
import { CheckCircleFilled, ShareAltOutlined } from '@ant-design/icons';
import axios from 'axios';
import dayjs from 'dayjs';
import PollResults from '@/components/polls/PollResults';
import type { StrawPoll } from '@/types/api';
import { STRAW_POLL_STATUS_LABELS, STRAW_POLL_TYPE_LABELS } from '@/types/api';
import { useAuthStore } from '@/stores/auth.store';

const { Title, Text, Paragraph } = Typography;

const apiBase = '/api';

export default function StrawPollPage() {
  const { slug } = useParams<{ slug: string }>();
  const { message: msg } = App.useApp();
  const { user, accessToken } = useAuthStore();
  const screens = Grid.useBreakpoint();
  const isMobile = !screens.md;

  const [poll, setPoll] = useState<StrawPoll | null>(null);
  const [loading, setLoading] = useState(true);
  const [selectedOption, setSelectedOption] = useState<string>('');
  const [voterName, setVoterName] = useState('');
  const [submitting, setSubmitting] = useState(false);
  const [hasVoted, setHasVoted] = useState(false);
  const [commentForm] = Form.useForm();

  const sseRef = useRef<EventSource | null>(null);

  const storedToken = localStorage.getItem(`straw_poll_voter_token_${slug}`);

  const fetchPoll = useCallback(async () => {
    if (!slug) return;
    try {
      const params: Record<string, string> = {};
      if (storedToken) params.voterToken = storedToken;
      const headers: Record<string, string> = {};
      if (accessToken) headers.Authorization = `Bearer ${accessToken}`;
      const { data } = await axios.get(`${apiBase}/straw-polls/public/${slug}`, { params, headers });
      setPoll(data);
      setHasVoted(!!data.hasVoted);
    } catch {
      setPoll(null);
    } finally {
      setLoading(false);
    }
  }, [slug, storedToken, accessToken]);

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

  // SSE for live results
  useEffect(() => {
    if (!slug || !poll || poll.resultVisibility !== 'LIVE') return;
    const es = new EventSource(`${apiBase}/straw-polls/public/${slug}/live`);
    sseRef.current = es;

    es.addEventListener('vote_update', (e) => {
      try {
        const data = JSON.parse(e.data);
        setPoll(prev => {
          if (!prev || !prev.options) return prev;
          const updated = prev.options.map(opt => {
            const count = data.optionCounts?.find((c: any) => c.optionId === opt.id);
            return count ? { ...opt, voteCount: count.count } : opt;
          });
          return { ...prev, options: updated, totalVotes: data.totalVotes };
        });
      } catch {}
    });

    es.addEventListener('poll_closed', () => {
      setPoll(prev => prev ? { ...prev, status: 'CLOSED' } : prev);
      msg.info('This poll has been closed');
    });

    es.addEventListener('comment_added', () => {
      fetchPoll(); // Refresh to get new comment
    });

    return () => { es.close(); };
  }, [slug, poll?.resultVisibility]);

  const handleVote = async () => {
    if (!selectedOption || !slug) return;
    setSubmitting(true);
    try {
      const body: any = { optionId: selectedOption };
      if (voterName) body.voterName = voterName;
      if (storedToken) body.voterToken = storedToken;

      const headers: Record<string, string> = { 'Content-Type': 'application/json' };
      if (accessToken) headers.Authorization = `Bearer ${accessToken}`;

      const { data } = await axios.post(`${apiBase}/straw-polls/public/${slug}/vote`, body, { headers });

      if (data.voterToken) {
        localStorage.setItem(`straw_poll_voter_token_${slug}`, data.voterToken);
      }

      setHasVoted(true);
      msg.success('Vote submitted!');
      fetchPoll();
    } catch (err: any) {
      msg.error(err.response?.data?.error || 'Failed to vote');
    } finally {
      setSubmitting(false);
    }
  };

  const handleComment = async (values: any) => {
    if (!slug) return;
    try {
      const headers: Record<string, string> = { 'Content-Type': 'application/json' };
      if (accessToken) headers.Authorization = `Bearer ${accessToken}`;
      await axios.post(`${apiBase}/straw-polls/public/${slug}/comment`, values, { headers });
      commentForm.resetFields();
      fetchPoll();
    } catch {
      msg.error('Failed to post comment');
    }
  };

  if (loading) return <Spin size="large" style={{ display: 'block', margin: '80px auto' }} />;
  if (!poll) return <Result status="404" title="Poll not found" />;
  if (poll.requiresAuth && !user) return <Result status="403" title="This poll requires authentication" />;

  const showVoteForm = poll.status === 'ACTIVE' && !hasVoted;
  const showResults = poll.showResults || hasVoted;

  return (
    <div style={{ padding: isMobile ? 16 : 32, maxWidth: 700, margin: '0 auto' }}>
      {/* Hero */}
      <div style={{ textAlign: 'center', marginBottom: 32 }}>
        <Space>
          <Tag>{STRAW_POLL_TYPE_LABELS[poll.type]}</Tag>
          <Tag color={poll.status === 'ACTIVE' ? 'green' : poll.status === 'CLOSED' ? 'orange' : 'default'}>
            {STRAW_POLL_STATUS_LABELS[poll.status]}
          </Tag>
        </Space>
        <Title level={2} style={{ marginTop: 12, marginBottom: 8 }}>{poll.title}</Title>
        {poll.description && <Paragraph type="secondary">{poll.description}</Paragraph>}
        {poll.createdBy && <Text type="secondary">by {poll.createdBy.name}</Text>}
        {poll.closesAt && poll.status === 'ACTIVE' && (
          <div style={{ marginTop: 8 }}>
            <Text type="secondary">Closes {dayjs(poll.closesAt).format('MMM D, YYYY h:mm A')}</Text>
          </div>
        )}
      </div>

      {/* Vote Form */}
      {showVoteForm && (
        <Card style={{ marginBottom: 24 }}>
          <Title level={4}>Cast Your Vote</Title>

          {poll.type === 'YES_NO_ABSTAIN' ? (
            <Space direction={isMobile ? 'vertical' : 'horizontal'} style={{ width: '100%', justifyContent: 'center', marginBottom: 16 }}>
              {poll.options?.map(opt => (
                <Button
                  key={opt.id}
                  type={selectedOption === opt.id ? 'primary' : 'default'}
                  size="large"
                  onClick={() => setSelectedOption(opt.id)}
                  style={{
                    minWidth: 120,
                    ...(opt.label === 'Yes' && selectedOption === opt.id ? { backgroundColor: '#52c41a', borderColor: '#52c41a' } : {}),
                    ...(opt.label === 'No' && selectedOption === opt.id ? { backgroundColor: '#ff4d4f', borderColor: '#ff4d4f' } : {}),
                  }}
                >
                  {opt.label}
                </Button>
              ))}
            </Space>
          ) : (
            <Radio.Group
              value={selectedOption}
              onChange={(e) => setSelectedOption(e.target.value)}
              style={{ width: '100%', marginBottom: 16 }}
            >
              <Space direction="vertical" style={{ width: '100%' }}>
                {poll.options?.map(opt => (
                  <Radio key={opt.id} value={opt.id} style={{ fontSize: 16, padding: '8px 0' }}>
                    {opt.label}
                  </Radio>
                ))}
              </Space>
            </Radio.Group>
          )}

          {(poll.identityMode === 'ANONYMOUS' || poll.identityMode === 'MIXED') && !user && (
            <Input
              placeholder="Your name (optional)"
              value={voterName}
              onChange={(e) => setVoterName(e.target.value)}
              style={{ marginBottom: 16, maxWidth: 300 }}
            />
          )}

          <Button
            type="primary"
            size="large"
            disabled={!selectedOption}
            loading={submitting}
            onClick={handleVote}
            block
          >
            Submit Vote
          </Button>
        </Card>
      )}

      {/* Already Voted */}
      {hasVoted && poll.status === 'ACTIVE' && (
        <Card style={{ marginBottom: 24, textAlign: 'center' }}>
          <CheckCircleFilled style={{ fontSize: 32, color: '#52c41a', marginBottom: 8 }} />
          <Title level={4} style={{ marginTop: 0 }}>You've voted!</Title>
          <Text type="secondary">Your vote has been recorded.</Text>
        </Card>
      )}

      {/* Results */}
      {showResults && poll.options && (
        <Card style={{ marginBottom: 24 }}>
          <Title level={4}>Results</Title>
          <PollResults
            options={poll.options}
            totalVotes={poll.totalVotes ?? poll._count?.votes ?? 0}
            type={poll.type}
          />
        </Card>
      )}

      {!showResults && poll.resultVisibility !== 'LIVE' && poll.resultVisibility !== 'PUBLIC_ALWAYS' && (
        <Card style={{ marginBottom: 24, textAlign: 'center' }}>
          <Text type="secondary">
            Results will be visible {poll.resultVisibility === 'AFTER_VOTE' ? 'after you vote' : poll.resultVisibility === 'AFTER_CLOSE' ? 'when the poll closes' : ''}
          </Text>
        </Card>
      )}

      {/* Share */}
      <div style={{ textAlign: 'center', marginBottom: 24 }}>
        <Button
          icon={<ShareAltOutlined />}
          onClick={() => {
            navigator.clipboard.writeText(window.location.href);
            msg.success('Link copied!');
          }}
        >
          Share This Poll
        </Button>
      </div>

      {/* Comments */}
      {poll.allowComments && (
        <>
          <Divider>Comments</Divider>
          <Form form={commentForm} layout="inline" onFinish={handleComment} style={{ marginBottom: 16, display: 'flex', gap: 8, flexWrap: 'wrap' }}>
            <Form.Item name="authorName" rules={[{ required: true, message: 'Name required' }]} style={{ flex: '0 0 auto' }}>
              <Input placeholder="Your name" defaultValue={user?.name || ''} />
            </Form.Item>
            <Form.Item name="content" rules={[{ required: true, message: 'Comment required' }]} style={{ flex: 1, minWidth: 200 }}>
              <Input placeholder="Add a comment..." />
            </Form.Item>
            <Button type="primary" htmlType="submit">Post</Button>
          </Form>

          {poll.comments && poll.comments.length > 0 ? (
            <List
              dataSource={poll.comments}
              renderItem={(comment: any) => (
                <List.Item>
                  <List.Item.Meta
                    title={comment.authorName}
                    description={comment.content}
                  />
                  <Text type="secondary" style={{ fontSize: 12 }}>{dayjs(comment.createdAt).format('MMM D, h:mm A')}</Text>
                </List.Item>
              )}
            />
          ) : (
            <Text type="secondary">No comments yet.</Text>
          )}
        </>
      )}
    </div>
  );
}
