import { useEffect, useState } from 'react';
import { Card, Typography, Progress, Tag, Skeleton, Empty, Tabs, List, Statistic, Row, Col, Switch, message } from 'antd';
import {
  TrophyOutlined, ScheduleOutlined, EnvironmentOutlined, MailOutlined,
  TeamOutlined, FireOutlined, StarOutlined, HomeOutlined, UserAddOutlined,
  CrownOutlined, EyeOutlined,
} from '@ant-design/icons';
import { api } from '@/lib/api';
import UserAvatar from '@/components/social/UserAvatar';
import type { AchievementWithProgress, VolunteerStats, LeaderboardEntry } from '@/types/social';

const { Title, Text } = Typography;

const ICON_MAP: Record<string, React.ReactNode> = {
  calendar: <ScheduleOutlined />,
  trophy: <TrophyOutlined />,
  environment: <EnvironmentOutlined />,
  home: <HomeOutlined />,
  star: <StarOutlined />,
  mail: <MailOutlined />,
  fire: <FireOutlined />,
  team: <TeamOutlined />,
  'usergroup-add': <UserAddOutlined />,
};

const CATEGORY_COLORS: Record<string, string> = {
  shifts: 'green',
  canvass: 'blue',
  campaigns: 'orange',
  social: 'purple',
};

export default function AchievementsPage() {
  const [achievements, setAchievements] = useState<AchievementWithProgress[]>([]);
  const [stats, setStats] = useState<VolunteerStats | null>(null);
  const [leaderboard, setLeaderboard] = useState<LeaderboardEntry[]>([]);
  const [leaderboardType, setLeaderboardType] = useState<string>('canvass');
  const [myRank, setMyRank] = useState<number | null>(null);
  const [loading, setLoading] = useState(true);
  const [leaderboardOptIn, setLeaderboardOptIn] = useState(true);
  const [optInLoading, setOptInLoading] = useState(false);

  useEffect(() => {
    fetchData();
    fetchOptInStatus();
  }, []);

  useEffect(() => {
    fetchLeaderboard(leaderboardType);
  }, [leaderboardType]);

  const fetchData = async () => {
    setLoading(true);
    try {
      const [achRes, statsRes] = await Promise.all([
        api.get('/social/achievements'),
        api.get('/social/achievements/stats'),
      ]);
      setAchievements(achRes.data.achievements);
      setStats(statsRes.data.stats);
    } catch {}
    setLoading(false);
  };

  const fetchOptInStatus = async () => {
    try {
      const { data } = await api.get('/social/spotlight/opt-in-status');
      setLeaderboardOptIn(data.showOnLeaderboard ?? true);
    } catch {}
  };

  const handleOptInToggle = async (checked: boolean) => {
    setOptInLoading(true);
    try {
      await api.post(checked ? '/social/spotlight/opt-in' : '/social/spotlight/opt-out');
      setLeaderboardOptIn(checked);
      message.success(checked ? 'You are now visible on public leaderboards' : 'You are now hidden from public leaderboards');
    } catch {
      message.error('Failed to update preference');
    } finally {
      setOptInLoading(false);
    }
  };

  const fetchLeaderboard = async (type: string) => {
    try {
      const { data } = await api.get('/social/achievements/leaderboard', { params: { type, limit: 10 } });
      setLeaderboard(data.leaderboard);
      setMyRank(data.myRank);
    } catch {}
  };

  if (loading) return <Skeleton active paragraph={{ rows: 8 }} />;

  const unlockedCount = achievements.filter((a) => a.unlocked).length;

  return (
    <div style={{ padding: '12px 0' }}>
      <Title level={4} style={{ margin: '0 0 12px 0' }}>
        <TrophyOutlined style={{ marginRight: 8 }} />
        Achievements
      </Title>

      {/* Stats summary */}
      {stats && (
        <Card size="small" style={{ marginBottom: 12 }}>
          <Row gutter={[12, 8]}>
            <Col span={8}>
              <Statistic title="Shifts" value={stats.shiftSignups} valueStyle={{ fontSize: 20 }} />
            </Col>
            <Col span={8}>
              <Statistic title="Doors" value={stats.canvassVisits} valueStyle={{ fontSize: 20 }} />
            </Col>
            <Col span={8}>
              <Statistic title="Campaigns" value={stats.campaignsParticipated} valueStyle={{ fontSize: 20 }} />
            </Col>
          </Row>
        </Card>
      )}

      {/* Achievement badges */}
      <Card
        title={`Badges (${unlockedCount}/${achievements.length})`}
        size="small"
        style={{ marginBottom: 12 }}
      >
        {achievements.length === 0 ? (
          <Empty description="No achievements available" />
        ) : (
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8 }}>
            {achievements.map((a) => (
              <Card
                key={a.id}
                size="small"
                style={{
                  width: 'calc(50% - 4px)',
                  opacity: a.unlocked ? 1 : 0.5,
                  borderColor: a.unlocked ? `var(--ant-color-${CATEGORY_COLORS[a.category]})` : undefined,
                }}
              >
                <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 4 }}>
                  <span style={{ fontSize: 20 }}>
                    {ICON_MAP[a.icon] || <TrophyOutlined />}
                  </span>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <Text strong ellipsis style={{ display: 'block', fontSize: 13 }}>
                      {a.name}
                    </Text>
                    <Tag
                      color={CATEGORY_COLORS[a.category]}
                      style={{ margin: 0, fontSize: 10, lineHeight: '16px' }}
                    >
                      {a.category}
                    </Tag>
                  </div>
                  {a.unlocked && <CrownOutlined style={{ color: '#faad14', fontSize: 16 }} />}
                </div>
                <Text type="secondary" style={{ fontSize: 11, display: 'block', marginBottom: 4 }}>
                  {a.description}
                </Text>
                <Progress
                  percent={Math.round((Math.min(a.progress, a.threshold) / a.threshold) * 100)}
                  size="small"
                  status={a.unlocked ? 'success' : 'active'}
                  format={() => `${Math.min(a.progress, a.threshold)}/${a.threshold}`}
                />
              </Card>
            ))}
          </div>
        )}
      </Card>

      {/* Leaderboard */}
      <Card
        title="Leaderboard"
        size="small"
        extra={
          <span style={{ display: 'flex', alignItems: 'center', gap: 6, fontSize: 12 }}>
            <EyeOutlined />
            <Switch
              size="small"
              checked={leaderboardOptIn}
              loading={optInLoading}
              onChange={handleOptInToggle}
            />
            <Typography.Text type="secondary" style={{ fontSize: 11 }}>
              {leaderboardOptIn ? 'Visible' : 'Hidden'}
            </Typography.Text>
          </span>
        }
      >
        <Tabs
          activeKey={leaderboardType}
          onChange={setLeaderboardType}
          size="small"
          items={[
            { key: 'canvass', label: 'Canvass' },
            { key: 'shifts', label: 'Shifts' },
            { key: 'campaigns', label: 'Campaigns' },
          ]}
        />
        {leaderboard.length === 0 ? (
          <Empty description="No data yet" />
        ) : (
          <>
            <List
              size="small"
              dataSource={leaderboard}
              renderItem={(entry) => (
                <List.Item
                  extra={<Text strong>{entry.score}</Text>}
                >
                  <List.Item.Meta
                    avatar={
                      <div style={{ position: 'relative' }}>
                        <UserAvatar userId={entry.userId} name={entry.name} email={entry.email} size={32} />
                        {entry.rank <= 3 && (
                          <span style={{
                            position: 'absolute', top: -4, right: -4,
                            background: entry.rank === 1 ? '#faad14' : entry.rank === 2 ? '#bfbfbf' : '#d48806',
                            borderRadius: '50%', width: 16, height: 16, display: 'flex',
                            alignItems: 'center', justifyContent: 'center', color: '#fff',
                            fontSize: 10, fontWeight: 700,
                          }}>
                            {entry.rank}
                          </span>
                        )}
                      </div>
                    }
                    title={entry.name || entry.email}
                    description={`#${entry.rank}`}
                  />
                </List.Item>
              )}
            />
            {myRank && (
              <div style={{ textAlign: 'center', marginTop: 8 }}>
                <Text type="secondary">Your rank: <Text strong>#{myRank}</Text></Text>
              </div>
            )}
          </>
        )}
      </Card>
    </div>
  );
}
