import VideoCameraOutlined from "@ant-design/icons/VideoCameraOutlined";
import { Button, Modal, Spin } from "antd";
import { useEffect, useRef, useState } from "react";
import Video from "zy-react-library/components/Video";
import { buildPlayableVideoSource, getVideoPlaybackFailureText } from "~/utils/video";

const PLAY_READY_TIMEOUT = 25000;
const PLAY_RETRY_INTERVAL = 5000;
const PLAY_SOURCE_TYPE = {
  HIKVISION: "hikvision",
  DATABASE: "database",
};

const VideoPlayModal = (props) => {
  const {
    onClose,
    videoName,
    videoAddress,
    cameraNumber,
    getPlayUrl,
    playSourceType = PLAY_SOURCE_TYPE.HIKVISION,
  } = props;
  const [playUrl, setPlayUrl] = useState("");
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);
  const [warningText, setWarningText] = useState("");
  const [originalPlayUrl, setOriginalPlayUrl] = useState("");
  const [playerKey, setPlayerKey] = useState(0);
  const getPlayUrlRef = useRef(getPlayUrl);
  const playerContainerRef = useRef(null);
  const retryIntervalRef = useRef(null);
  const failTimerRef = useRef(null);
  const requestRunningRef = useRef(false);
  const requestTaskIdRef = useRef(0);
  const playUrlRef = useRef("");
  const originalPlayUrlRef = useRef("");
  const upgradedToHttpsRef = useRef(false);

  const clearPlayTimers = () => {
    if (retryIntervalRef.current) {
      window.clearInterval(retryIntervalRef.current);
      retryIntervalRef.current = null;
    }
    if (failTimerRef.current) {
      window.clearTimeout(failTimerRef.current);
      failTimerRef.current = null;
    }
  };

  const clearPlayableUrl = () => {
    playUrlRef.current = "";
    originalPlayUrlRef.current = "";
    upgradedToHttpsRef.current = false;
    setPlayUrl("");
    setWarningText("");
    setOriginalPlayUrl("");
  };

  const isPlayerReady = () => {
    const videoEl = playerContainerRef.current?.querySelector("video");
    return !!videoEl && videoEl.readyState >= 2;
  };

  const syncPlayableUrl = (url) => {
    const nextSource = buildPlayableVideoSource(url);
    playUrlRef.current = nextSource.source;
    originalPlayUrlRef.current = nextSource.originalSource;
    upgradedToHttpsRef.current = nextSource.upgradedToHttps;
    setPlayUrl(nextSource.source);
    setOriginalPlayUrl(nextSource.originalSource);
    setWarningText(nextSource.warningText);
    setPlayerKey(prev => prev + 1);
  };

  useEffect(() => {
    getPlayUrlRef.current = getPlayUrl;
  }, [getPlayUrl]);

  useEffect(() => {
    return () => {
      clearPlayTimers();
    };
  }, []);

  useEffect(() => {
    const useHikvisionPlayUrl = playSourceType === PLAY_SOURCE_TYPE.HIKVISION;
    const hasFallbackAddress = videoAddress?.startsWith("http");
    const canTryPlay = useHikvisionPlayUrl ? (!!cameraNumber || hasFallbackAddress) : hasFallbackAddress;

    requestTaskIdRef.current += 1;
    const currentTaskId = requestTaskIdRef.current;
    requestRunningRef.current = false;
    clearPlayTimers();
    clearPlayableUrl();
    setError(null);

    const requestLatestPlayUrl = async () => {
      if (requestRunningRef.current) {
        return false;
      }
      requestRunningRef.current = true;
      try {
        let nextUrl = "";
        if (useHikvisionPlayUrl && cameraNumber && getPlayUrlRef.current) {
          const { data } = await getPlayUrlRef.current({ indexCode: cameraNumber });
          nextUrl = data?.url || data || "";
        }
        else if (hasFallbackAddress) {
          nextUrl = videoAddress;
        }

        if (requestTaskIdRef.current !== currentTaskId) {
          return false;
        }

        if (nextUrl) {
          syncPlayableUrl(nextUrl);
          setError(null);
          return true;
        }

        return false;
      }
      catch {
        return false;
      }
      finally {
        if (requestTaskIdRef.current === currentTaskId) {
          requestRunningRef.current = false;
        }
      }
    };

    const attemptPlayback = async () => {
      if (requestTaskIdRef.current !== currentTaskId || isPlayerReady()) {
        clearPlayTimers();
        setLoading(false);
        return;
      }

      setError(null);
      if (!playUrlRef.current) {
        setLoading(true);
      }

      await requestLatestPlayUrl();

      if (requestTaskIdRef.current !== currentTaskId) {
        return;
      }

      if (playUrlRef.current) {
        setLoading(false);
      }
    };

    if (!canTryPlay) {
      setLoading(false);
      setError("暂无视频播放地址");
      return () => {
        requestRunningRef.current = false;
        clearPlayTimers();
      };
    }

    setLoading(true);
    attemptPlayback();

    // 首次起流慢时，每 5 秒重新向后端获取一次最新地址，而不是只重建旧播放器实例。
    retryIntervalRef.current = window.setInterval(() => {
      attemptPlayback();
    }, PLAY_RETRY_INTERVAL);

    failTimerRef.current = window.setTimeout(() => {
      if (requestTaskIdRef.current !== currentTaskId || isPlayerReady()) {
        clearPlayTimers();
        setLoading(false);
        return;
      }

      clearPlayTimers();
      setLoading(false);
      if (!originalPlayUrlRef.current && useHikvisionPlayUrl && cameraNumber) {
        setError("获取播放地址失败，请检查流媒体服务状态。");
        return;
      }
      setError(getVideoPlaybackFailureText({
        originalSource: originalPlayUrlRef.current,
        upgradedToHttps: upgradedToHttpsRef.current,
      }));
    }, PLAY_READY_TIMEOUT);

    return () => {
      requestRunningRef.current = false;
      clearPlayTimers();
    };
  }, [videoAddress, cameraNumber, playSourceType]);

  const bodyStyle = {
    padding: 0,
    background: "#000",
  };

  const playerBoxStyle = {
    width: "100%",
    height: 500,
    background: "#000",
    display: "flex",
    alignItems: "center",
    justifyContent: "center",
    color: "#fff",
    fontSize: 16,
    position: "relative",
    overflow: "hidden",
  };

  const renderStatusBox = (content) => {
    return (
      <div
        style={playerBoxStyle}
      >
        <div style={{ textAlign: "center", maxWidth: 560, padding: "0 24px" }}>
          {content}
        </div>
      </div>
    );
  };

  if (error) {
    return (
      <Modal
        open
        title={videoName || "视频播放"}
        width={800}
        onCancel={onClose}
        footer={null}
        styles={{ body: bodyStyle }}
      >
        {renderStatusBox(
          <>
            <VideoCameraOutlined style={{ fontSize: 48, marginBottom: 16, color: "#666" }} />
            <div style={{ color: "#d9d9d9", lineHeight: "24px" }}>{error}</div>
            {originalPlayUrl && (
              <div style={{ marginTop: 16, color: "#8c8c8c", fontSize: 12, wordBreak: "break-all" }}>
                播放地址：
                {originalPlayUrl}
              </div>
            )}
            <Button type="primary" style={{ marginTop: 20 }} onClick={onClose}>关闭</Button>
          </>,
        )}
      </Modal>
    );
  }

  if (loading) {
    return (
      <Modal
        open
        title={videoName || "视频播放"}
        width={800}
        onCancel={onClose}
        footer={null}
        styles={{ body: bodyStyle }}
      >
        {renderStatusBox(
          <>
            <Spin size="large" style={{ marginBottom: 16 }} />
            <div>正在加载视频...</div>
          </>,
        )}
      </Modal>
    );
  }

  return (
    <Modal
      open
      title={videoName || "视频播放"}
      width={800}
      onCancel={onClose}
      footer={null}
      styles={{ body: bodyStyle }}
    >
      <div ref={playerContainerRef} style={playerBoxStyle}>
        {playUrl
          ? <Video key={`${playerKey}-${playUrl}`} height="100%" width="100%" source={playUrl} isLive />
          : <div style={{ textAlign: "center", maxWidth: 560, padding: "0 24px" }}>暂无视频播放地址</div>}
      </div>
      {(warningText || originalPlayUrl) && (
        <div style={{ padding: "12px 16px", background: "#141414", color: "#d9d9d9", fontSize: 12, lineHeight: "20px" }}>
          {warningText && <div>{warningText}</div>}
          {originalPlayUrl && (
            <div style={{ marginTop: warningText ? 8 : 0, wordBreak: "break-all", color: "#8c8c8c" }}>
              原始地址：
              {originalPlayUrl}
            </div>
          )}
        </div>
      )}
    </Modal>
  );
};

export default VideoPlayModal;
