import React from 'react';
import { Card, Tag, Button, Avatar, Badge } from 'antd';
import { EyeOutlined, CommentOutlined, UserOutlined, ClockCircleOutlined, HeartOutlined, CrownOutlined } from '@ant-design/icons';
import { history } from 'umi';
import styles from './PostCard.module.css';
import { Post } from '../PostCenter/types';

interface PostCardProps {
  post: Post;
}

const PostCard: React.FC<PostCardProps> = ({ post }) => {
  const {
    id,
    title,
    author,
    publishTime,
    tags,
    views,
    comments,
    favorites,
    likes,
    coverImage,
    summary,
    promotionPlanId,
    isPromoted
  } = post;

  const goToDetail = () => {
    history.push(`/post-detail/${id}`);
  };

  return (
    <div className={styles.postCardWrapper}>
      <Card
        hoverable
        cover={
          <div className={styles.coverContainer}>
            {isPromoted && (
              <div className={styles.promotionBadge}>
                <CrownOutlined />
                <span>推广</span>
              </div>
            )}
            <img 
              alt={title} 
              src={coverImage} 
              className={styles.coverImage}
              onError={(e) => {
                e.currentTarget.src = '/images/404.png';
              }}
            />
          </div>
        }
        className={styles.postCard}
        bodyStyle={{ padding: '16px', height: '240px', display: 'flex', flexDirection: 'column' }}
      >
        <div className={styles.cardContent}>
          <h3 className={styles.postTitle} title={title}>{title}</h3>
          
          <div className={styles.postMeta}>
            <Avatar size="small" style={{ marginRight: 6 }} icon={<UserOutlined />}>
              {author && author[0]}
            </Avatar>
            <span className={styles.authorName}>{author}</span>
            <ClockCircleOutlined style={{ marginLeft: 12, marginRight: 4 }} />
            <span className={styles.publishTime}>{publishTime}</span>
          </div>
          
          <div className={styles.tagsContainer}>
            {(Array.isArray(tags) ? tags : []).slice(0, 3).map(tag => (
              <Tag color="blue" key={tag} className={styles.tag}>{tag}</Tag>
            ))}
            {tags && tags.length > 3 && (
              <Tag color="default" className={styles.tag}>+{tags.length - 3}</Tag>
            )}
          </div>
          
          <div className={styles.postSummary} title={summary}>{summary}</div>
          
          <div className={styles.postFooter}>
            <div className={styles.stats}>
              <span className={styles.statItem}>
                <EyeOutlined /> {views || 0}
              </span>
              <span className={styles.statItem}>
                <CommentOutlined /> {comments || 0}
              </span>
              <span className={styles.statItem}>
                <HeartOutlined /> {favorites || 0}
              </span>
            </div>
            <Button 
              type="link" 
              className={styles.readMoreBtn}
              onClick={goToDetail}
            >
              查看更多 »
            </Button>
          </div>
        </div>
      </Card>
    </div>
  );
};

export default PostCard; 