// components/my-video/index.ts
import { AES_KEY, AES_IV } from "../../env";
import { request } from "../../utils/request";
import { aesEncrypt } from "../../utils/crypto";

interface VideoData {
  screen: boolean;
  playing: boolean;
  currentTime: number;
  isReady: boolean;
  sendDurationTimer: number | null;
  lastUpdateTime: number;
  isConnected: boolean; // 新增网络连接状态字段
}
interface MyVideoComponent {
  data: VideoData;
  videoContext: WechatMiniprogram.VideoContext | null;
  pauseVideoHandler?: () => void;
  resumeVideoHandler?: () => void;
  setData: (d: Partial<VideoData>, cb?: () => void) => void;
  initNetworkListener: () => void;
  startSendProgress: () => void;
  clearSendProgressTimer: () => void;
  sendProgress: () => Promise<void>;
}

Component({
  properties: {
    src: String,
    backgroundUrl: String,
  },

  data: {
    screen: false,
    playing: false,
    currentTime: 0,
    isReady: false,
    isConnected: false,
    sendDurationTimer: 0,
    lastUpdateTime: 0,
  } as VideoData,

  lifetimes: {
    attached(this: MyVideoComponent) {
      this.initNetworkListener();

      // 获取 videoContext 并初始化
      this.videoContext = wx.createVideoContext("videoPlayer", this as any);

      const pauseVideo = () => {
        if (this.data.playing) {
          wx.setStorageSync("interruptedTime", this.data.currentTime);
          this.videoContext?.pause();
          this.setData({ playing: false });
          this.clearSendProgressTimer();
        }
      };

      const resumeVideo = () => {
        if (!this.videoContext) {
          this.videoContext = wx.createVideoContext("videoPlayer", this as any);
        }
        this.videoContext.pause();
      };

      this.pauseVideoHandler = pauseVideo;
      this.resumeVideoHandler = resumeVideo;

      wx.onAudioInterruptionBegin(this.pauseVideoHandler);
      wx.onAudioInterruptionEnd(this.resumeVideoHandler);
      wx.onAppHide(this.pauseVideoHandler);
      wx.onAppShow(this.resumeVideoHandler);
    },

    detached(this: MyVideoComponent) {
      if (this.pauseVideoHandler) {
        wx.offAudioInterruptionBegin(this.pauseVideoHandler);
        wx.offAppHide(this.pauseVideoHandler);
      }
      if (this.resumeVideoHandler) {
        wx.offAudioInterruptionEnd(this.resumeVideoHandler);
        wx.offAppShow(this.resumeVideoHandler);
      }
      this.clearSendProgressTimer();
      this.videoContext = null;
    },
  },

  methods: {
    initNetworkListener(this: MyVideoComponent) {
      // 首先获取当前网络状态
      wx.getNetworkType({
        success: (res) => {
          this.setData({
            isConnected: res.networkType !== "none",
          });
        },
      });
      wx.onNetworkStatusChange(
        (res: WechatMiniprogram.OnNetworkStatusChangeCallbackResult) => {
          this.setData({
            isConnected: res.isConnected,
          });
          if (!res.isConnected && this.data.playing) {
            this.videoContext?.pause();
            this.setData({ playing: false });
            wx.showToast({
              title: "网络连接已断开",
              icon: "none",
              duration: 2000,
            });
          }
          if (res.isConnected) {
            wx.showToast({
              title: "网络已连接",
              icon: "success",
              duration: 1500,
            });
          }
        }
      );
    },

    handleLoadedMetadata(this: MyVideoComponent) {
      this.setData({ isReady: true });
    },

    handlePosterTap(this: MyVideoComponent) {
      if (!this.videoContext || !this.data.isReady) return;
      if (!this.data.isConnected) {
        wx.showToast({
          title: "网络连接异常，请检查网络设置",
          icon: "none",
          duration: 2000,
        });
        return;
      }

      const newPlaying = !this.data.playing;
      const resumeTime =
        (wx.getStorageSync("interruptedTime") as number) ||
        this.data.currentTime ||
        (wx.getStorageSync("currentTime") as number) ||
        0;

      if (newPlaying) {
        if (resumeTime > 0) {
          this.videoContext.seek(resumeTime);
        }
        this.videoContext.play();
        if (!this.data.sendDurationTimer) {
          this.startSendProgress();
        }
      } else {
        this.videoContext.pause();
        this.clearSendProgressTimer();
      }

      this.setData({ playing: newPlaying });
      wx.removeStorageSync("interruptedTime");
    },

    handlePause(this: MyVideoComponent) {
      wx.setStorageSync("interruptedTime", this.data.currentTime);
      this.setData({ playing: false });
      this.clearSendProgressTimer();
    },

    handleTimeUpdate(
      this: MyVideoComponent,
      e: WechatMiniprogram.VideoTimeUpdate
    ) {
      const now = Date.now();
      const currentTime = Math.floor(e.detail.currentTime ?? 0);
      if (now - this.data.lastUpdateTime >= 1000) {
        this.setData({ currentTime });
        (this.data as VideoData).lastUpdateTime = now;
        wx.setStorageSync("currentTime", currentTime);
      }
    },

    handleEnded(this: MyVideoComponent) {
      this.sendProgress();
      wx.setStorageSync("ended", true);
      this.setData({ playing: false, currentTime: 0 });
      wx.removeStorageSync("currentTime");
      wx.removeStorageSync("interruptedTime");
      this.clearSendProgressTimer();
    },

    handleFullscreenChange(this: MyVideoComponent) {
      const newScreen = !this.data.screen;
      if (newScreen) {
        this.videoContext?.requestFullScreen({ direction: 90 });
      } else {
        this.videoContext?.exitFullScreen();
      }
      this.setData({ screen: newScreen });
    },

    handleError(this: MyVideoComponent, e: WechatMiniprogram.VideoError) {
      console.error("播放错误：", e.detail.errMsg);
      this.setData({ playing: false });
    },

    startSendProgress(this: MyVideoComponent) {
      this.clearSendProgressTimer();
      const timer = setInterval(() => {
        this.sendProgress();
      }, 15000) as unknown as number;
      this.setData({ sendDurationTimer: timer });
    },

    clearSendProgressTimer(this: MyVideoComponent) {
      const t = this.data.sendDurationTimer;
      if (t) {
        clearInterval(t);
        this.setData({ sendDurationTimer: 0 });
      }
    },

    async sendProgress(this: MyVideoComponent) {
      try {
        const openId = wx.getStorageSync("openId");
        const code = wx.getStorageSync("code");
        const state = wx.getStorageSync("state");
        const seeId = wx.getStorageSync("seeId");
        const duration = this.data.currentTime + 1;
        if (code) {
          const params = {
            openId,
            code,
            duration
          };
          await request({
            options: {
              url: `/app/video-watch/inspect`,
              data: aesEncrypt(JSON.stringify(params), AES_KEY, AES_IV),
            },
            isLoading: false,
          });
        } else {
          const params = {
            openId,
            state,
            seeId,
            duration
          };
          await request({
            options: {
              url: `/app/watch/inspect`,
              data: aesEncrypt(JSON.stringify(params), AES_KEY, AES_IV),
            },
            isLoading: false,
          });
        }
      } catch (err) {
        console.error("上报观看进度失败:", err);
      }
    },
  },
});
