import { Button, Card, Statistic, Typography } from "antd";
import type { IEventInfo } from "../types";
import dayjs from "dayjs";
import utc from 'dayjs/plugin/utc';
import timezone from 'dayjs/plugin/timezone';
import { BellFilled, BellOutlined, EyeOutlined } from "@ant-design/icons";
import { useCallback, useContext, useEffect, useMemo, useState } from "react";
import { useNavigate } from "react-router";
import type { TimerType } from "antd/lib/statistic/Timer";
import { useLogto } from "@logto/react";
import { useAuthHeaders } from "../hooks/useAuthHeaders";
import { useRequest } from "ahooks";
import { WebScoketContext } from "../context/WebsocketContext";
import { getEventSubKey } from "../utils/common";

dayjs.extend(utc);
dayjs.extend(timezone);

interface EventCardProps {
  eventInfo: IEventInfo;
}

export function EventCard(props: EventCardProps) {
  const { eventInfo: e } = props;
  const day = useMemo(() => dayjs.tz(e.startDate, 'Asia/Tokyo'), [e]);
  const navigate = useNavigate();
  const handleView = useCallback(() => {
    navigate(`/event/${e.matchId}`);
  }, [e]);
  const [messageFormat, setMessageFormat] = useState('');
  const getStatisticProps = useCallback((): {
    format: string;
    type: TimerType;
  } => {
    if (e.isFinished) {
      if (dayjs().diff(day, 'days') < 1) return {
        type: 'countdown',
        format: `已结束`,
      };
      return {
        type: 'countup',
        format: `已结束 DD 天`,
      };
    }
    if (e.isProcessing) {
      return {
        type: 'countup',
        format: '比赛进行中 HH:mm',
      }
    }
    if (dayjs().diff(day, 'days') === 0) {
      return {
        type: 'countdown',
        format: `距离比赛开始还有 HH:mm`,
      };
    }
    return {
      type: 'countdown',
      format: `距离比赛开始还有 DD 天 HH:mm`,
    };
  }, [e, day]);
  const [statisticType, setStatisticType] = useState<TimerType>('countdown');
  const updateMessageFormat = useCallback(() => {
    const statistic = getStatisticProps();
    setMessageFormat(statistic.format);
    setStatisticType(statistic.type);
    // console.debug('format: %s', day.format(statistic.format), statistic);
  }, [getStatisticProps])
  const { isAuthenticated } = useLogto();
  const { messageSender } = useContext(WebScoketContext);
  const headers = useAuthHeaders();
  const isSubscried = useRequest(async () => {
    return fetch(`/api/subscribe-event/${e.matchId}`, {
      headers,
    })
      .then(res => res.json())
      .then(json => json.isSub);
  }, { refreshDeps: [headers], debounceWait: 300 })
  const subReq = useRequest(async () => {
    return fetch(`/api/subscribe-event/${e.matchId}`, {
      headers,
      method: 'PUT',
    });
  }, { manual: true, refreshDeps: [e, headers], debounceWait: 300 });
  const unSubReq = useRequest(async () => {
    return fetch(`/api/subscribe-event/${e.matchId}`, {
      headers,
      method: 'DELETE',
    });
  }, { manual: true, refreshDeps: [e, headers], debounceWait: 300 });
  const [subLoading, setSubloading] = useState(false);
  const handleSub = useCallback(async () => {
    setSubloading(true);
    await subReq.runAsync();
    await isSubscried.runAsync();
    messageSender?.('SUB', { topic: getEventSubKey(e.matchId) });
    setSubloading(false);
  }, [e, subReq, isSubscried]);
  const handleUnSub = useCallback(async () => {
    setSubloading(true);
    await unSubReq.runAsync();
    await isSubscried.runAsync();
    messageSender?.('UNSUB', { topic: getEventSubKey(e.matchId) });
    setSubloading(false);
  }, [e, isSubscried, unSubReq]);
  useEffect(() => {
    const timeout = day.toDate().getTime() - Date.now();
    updateMessageFormat();
    const id = setTimeout(() => {
      updateMessageFormat();
    }, timeout);
    return () => clearTimeout(id);
  }, [updateMessageFormat]);
  const isSubBtnDisabled = useMemo(() => {
    if (!isAuthenticated) return true;
    if (subLoading) return true;
    if (e.isFinished && !isSubscried.data) return true;
    return false;
  }, [isAuthenticated, subLoading, isSubscried]);
  return (
    <Card
      key={e.matchId}
      title={e.title}
      style={{ width: '100%' }}
      actions={[
        <Button
          type="link"
          loading={subLoading}
          disabled={isSubBtnDisabled}
          icon={isSubscried.data ? <BellFilled style={{ color: 'yellow' }} /> :<BellOutlined />}
          onClick={isSubscried.data ? handleUnSub : handleSub}
        >
          {isSubscried.data ? '取消提醒' : '提醒我'}
        </Button>,
        <Button
          type="link"
          onClick={handleView}
          icon={<EyeOutlined  />}
        >
          查看
        </Button>,
      ]}
    >
      <Typography.Text type={e.isFinished ? 'secondary' : 'success'}>{e.title}</Typography.Text>
      <Statistic.Timer
        type={statisticType}
        value={day.toDate().getTime()}
        format={messageFormat}
        styles={{ content: e.isFinished ? { color: 'gray' } : {} }}
      />
      {e.info.map(e => (
        <div key={e}>
          <Typography.Text type='secondary'>{e}</Typography.Text>
        </div>
      ))}
    </Card>
  )
}