import { useEffect, useState, useCallback } from 'react';
import { useParams, useNavigate } from 'react-router-dom';
import { Typography, Spin, Card, Tag, Space, Button, Divider, Descriptions, App } from 'antd';
import {
  ArrowLeftOutlined,
  ClockCircleOutlined,
  LogoutOutlined,
} from '@ant-design/icons';
import dayjs from 'dayjs';
import { api } from '@/lib/api';
import { useAuthStore } from '@/stores/auth.store';
import { METRIC_MAP, STATUS_COLORS } from '@/components/social/ChallengeCard';
import ChallengeLeaderboard from '@/components/social/ChallengeLeaderboard';
import TeamJoinCard from '@/components/social/TeamJoinCard';
import { getErrorMessage } from '@/utils/getErrorMessage';

interface ChallengeDetail {
  id: string;
  title: string;
  description: string | null;
  metric: string;
  status: string;
  startsAt: string;
  endsAt: string;
  minTeamSize: number;
  maxTeamSize: number;
  maxTeams: number | null;
  createdBy: { name: string | null; email: string };
  teams: Array<{
    id: string;
    name: string;
    score: number;
    captainUserId: string;
    captain: { id: string; name: string | null; email: string };
    members: Array<{
      id: number;
      userId: string;
      score: number;
      user: { id: string; name: string | null; email: string };
    }>;
  }>;
}

export default function ChallengeDetailPage() {
  const { id } = useParams<{ id: string }>();
  const navigate = useNavigate();
  const { message } = App.useApp();
  const { user } = useAuthStore();

  const [challenge, setChallenge] = useState<ChallengeDetail | null>(null);
  const [myTeam, setMyTeam] = useState<ChallengeDetail['teams'][0] | null>(null);
  const [loading, setLoading] = useState(true);
  const [leaving, setLeaving] = useState(false);

  const load = useCallback(async () => {
    if (!id) return;
    setLoading(true);
    try {
      const [challengeRes, myTeamRes] = await Promise.all([
        api.get(`/social/challenges/${id}`),
        api.get(`/social/challenges/${id}/my-team`),
      ]);
      setChallenge(challengeRes.data);
      setMyTeam(myTeamRes.data.team);
    } catch {
      message.error('Failed to load challenge');
    } finally {
      setLoading(false);
    }
  }, [id]); // eslint-disable-line react-hooks/exhaustive-deps

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

  const handleLeave = async () => {
    if (!myTeam || !id) return;
    setLeaving(true);
    try {
      await api.post(`/social/challenges/${id}/teams/${myTeam.id}/leave`);
      message.success('Left team');
      load();
    } catch (err: unknown) {
      message.error(getErrorMessage(err, 'Failed to leave team'));
    } finally {
      setLeaving(false);
    }
  };

  if (loading || !challenge) {
    return <div style={{ textAlign: 'center', padding: 48 }}><Spin size="large" /></div>;
  }

  const metric = (METRIC_MAP[challenge.metric] || METRIC_MAP.DOORS_KNOCKED)!;
  const isJoinable = challenge.status === 'UPCOMING' || challenge.status === 'ACTIVE';
  const isActive = challenge.status === 'ACTIVE';
  const isUpcoming = challenge.status === 'UPCOMING';

  const endsIn = dayjs(challenge.endsAt).diff(dayjs(), 'second');
  const startsIn = dayjs(challenge.startsAt).diff(dayjs(), 'second');

  const countdownLabel =
    isActive && endsIn > 0
      ? `Ends in ${Math.floor(endsIn / 86400)}d ${Math.floor((endsIn % 86400) / 3600)}h`
      : isUpcoming && startsIn > 0
        ? `Starts in ${Math.floor(startsIn / 86400)}d ${Math.floor((startsIn % 86400) / 3600)}h`
        : null;

  return (
    <div>
      <Button
        type="text"
        icon={<ArrowLeftOutlined />}
        onClick={() => navigate('/volunteer/challenges')}
        style={{ marginBottom: 8, padding: 0 }}
      >
        Back
      </Button>

      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: 16 }}>
        <div>
          <Typography.Title level={3} style={{ margin: 0 }}>
            {challenge.title}
          </Typography.Title>
          {challenge.description && (
            <Typography.Paragraph type="secondary" style={{ marginTop: 4 }}>
              {challenge.description}
            </Typography.Paragraph>
          )}
        </div>
        <Tag color={STATUS_COLORS[challenge.status]}>{challenge.status}</Tag>
      </div>

      <Descriptions size="small" column={{ xs: 1, sm: 2, md: 3 }} style={{ marginBottom: 16 }}>
        <Descriptions.Item label="Metric">
          <Tag icon={metric.icon} color={metric.color}>{metric.label}</Tag>
        </Descriptions.Item>
        <Descriptions.Item label="Period">
          {dayjs(challenge.startsAt).format('MMM D')} - {dayjs(challenge.endsAt).format('MMM D, YYYY')}
        </Descriptions.Item>
        <Descriptions.Item label="Team Size">
          {challenge.minTeamSize} - {challenge.maxTeamSize}
        </Descriptions.Item>
      </Descriptions>

      {countdownLabel && (
        <Tag icon={<ClockCircleOutlined />} color="processing" style={{ marginBottom: 16 }}>
          {countdownLabel}
        </Tag>
      )}

      <Divider orientation="left">Leaderboard</Divider>

      <ChallengeLeaderboard
        teams={challenge.teams}
        myTeamId={myTeam?.id}
      />

      <Divider orientation="left">My Team</Divider>

      {myTeam ? (
        <Card size="small">
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 8 }}>
            <Typography.Title level={5} style={{ margin: 0 }}>{myTeam.name}</Typography.Title>
            {isJoinable && (
              <Button
                size="small"
                danger
                icon={<LogoutOutlined />}
                loading={leaving}
                onClick={handleLeave}
              >
                Leave
              </Button>
            )}
          </div>
          <Space direction="vertical" size={2} style={{ width: '100%' }}>
            {myTeam.members.map((m) => (
              <div key={m.id} style={{ display: 'flex', justifyContent: 'space-between' }}>
                <span>
                  {m.userId === myTeam.captainUserId ? '(C) ' : ''}
                  {m.user.name || m.user.email}
                  {m.userId === user?.id ? ' (you)' : ''}
                </span>
                <Typography.Text strong>{m.score}</Typography.Text>
              </div>
            ))}
          </Space>
        </Card>
      ) : isJoinable ? (
        <TeamJoinCard
          challengeId={challenge.id}
          teams={challenge.teams}
          maxTeamSize={challenge.maxTeamSize}
          onTeamCreated={load}
          onTeamJoined={load}
        />
      ) : (
        <Typography.Text type="secondary">
          This challenge is not accepting new teams.
        </Typography.Text>
      )}
    </div>
  );
}
