import { useEffect, useState } from 'react';

import { DeviceInfo, PlaybackStatus } from './ExpoDlnaPlayer.types';
import ExpoDlnaPlayerModule from './ExpoDlnaPlayerModule';

export * from './ExpoDlnaPlayer.types';

/**
 * 检查设备是否已连接
 * @returns {boolean} 是否已连接到设备
 */
export function useDeviceConnectivity() {
  const [isConnected, setIsConnected] = useState(false);

  useEffect(() => {
    // 初始检查
    const checkInitialStatus = async () => {
      try {
        const connected = await ExpoDlnaPlayerModule.isConnected();
        setIsConnected(connected);
      } catch (error) {
        console.error('[Expo DLNA Player] 检查连接状态失败:', error);
      }
    };

    checkInitialStatus();

    // 监听连接状态变化
    const subscription = ExpoDlnaPlayerModule.addListener(
      'onConnectionChanged',
      (params) => {
        setIsConnected(params.connected);
      }
    );

    return () => {
      subscription.remove();
    };
  }, []);
  
  return isConnected;
}

/**
 * 开始搜索可用的DLNA设备
 */
export async function startDiscovery(): Promise<void> {
  try {
    console.log('[Expo DLNA Player] 开始搜索设备...');
    return await ExpoDlnaPlayerModule.startDiscovery();
  } catch (error) {
    console.error('[Expo DLNA Player] 启动设备搜索失败:', error);
    throw error;
  }
}

/**
 * 停止设备搜索
 */
export async function stopDiscovery(): Promise<void> {
  try {
    console.log('[Expo DLNA Player] 停止搜索设备');
    return await ExpoDlnaPlayerModule.stopDiscovery();
  } catch (error) {
    console.error('[Expo DLNA Player] 停止设备搜索失败:', error);
    throw error;
  }
}

/**
 * 获取已发现的设备列表
 * @returns 设备信息数组
 */
export async function getDevices(): Promise<any[]> {
  try {
    return await ExpoDlnaPlayerModule.getDevices();
  } catch (error) {
    console.error('[Expo DLNA Player] 获取设备列表失败:', error);
    throw error;
  }
}

/**
 * 连接到DLNA/AirPlay设备
 * @param deviceId 设备ID
 * @returns 是否连接成功
 */
export async function connectToDevice(deviceId: string): Promise<boolean> {
  try {
    console.log(`[Expo DLNA Player] 连接到设备: ${deviceId}`);

    // 获取设备信息
    const deviceInfoList = await ExpoDlnaPlayerModule.getDevices();
    const device = deviceInfoList.find(d => d.id === deviceId);

    if (!device) {
      console.error(`[Expo DLNA Player] 设备未找到: ${deviceId}`);
      return false;
    }

    if (device.type === 'dlna' && !device.controlURL) {
      console.warn(`[Expo DLNA Player] 警告: DLNA设备缺少controlURL, 设备ID: ${deviceId}`);
    }

    return await ExpoDlnaPlayerModule.connectToDevice(deviceId);
  } catch (error) {
    console.error('[Expo DLNA Player] 连接设备失败:', error);
    throw error;
  }
}

/**
 * 断开当前连接的设备
 */
export async function disconnectFromDevice(): Promise<void> {
  try {
    console.log('[Expo DLNA Player] 断开设备连接');
    return await ExpoDlnaPlayerModule.disconnectFromDevice();
  } catch (error) {
    console.error('[Expo DLNA Player] 断开设备连接失败:', error);
    throw error;
  }
}

/**
 * 检查是否已连接到设备
 * @returns 是否已连接
 */
export async function isConnected(): Promise<boolean> {
  try {
    return await ExpoDlnaPlayerModule.isConnected();
  } catch (error) {
    console.error('[Expo DLNA Player] 检查连接状态失败:', error);
    throw error;
  }
}

/**
 * 获取当前连接的设备信息
 * @returns 设备信息，如果未连接则返回null
 */
export async function getConnectedDevice(): Promise<any | null> {
  try {
    return await ExpoDlnaPlayerModule.getConnectedDevice();
  } catch (error) {
    console.error('[Expo DLNA Player] 获取连接设备信息失败:', error);
    throw error;
  }
}

/**
 * 播放媒体
 * @param url 媒体URL
 * @param title 媒体标题
 * @param mimeType 媒体类型
 */
export async function play(url: string, title?: string, mimeType?: string): Promise<void> {
  try {
    return await ExpoDlnaPlayerModule.play(url, title, mimeType);
  } catch (error) {
    console.error('[Expo DLNA Player] 播放媒体失败:', error);
    throw error;
  }
}

/**
 * 暂停当前播放
 */
export async function pause(): Promise<void> {
  try {
    return await ExpoDlnaPlayerModule.pause();
  } catch (error) {
    console.error('[Expo DLNA Player] 暂停播放失败:', error);
    throw error;
  }
}

/**
 * 恢复播放
 */
export async function resume(): Promise<void> {
  try {
    return await ExpoDlnaPlayerModule.resume();
  } catch (error) {
    console.error('[Expo DLNA Player] 恢复播放失败:', error);
    throw error;
  }
}

/**
 * 停止播放
 */
export async function stop(): Promise<void> {
  try {
    return await ExpoDlnaPlayerModule.stop();
  } catch (error) {
    console.error('[Expo DLNA Player] 停止播放失败:', error);
    throw error;
  }
}

/**
 * 跳转到指定位置
 * @param position 位置（秒）
 */
export async function seek(position: number): Promise<void> {
  try {
    return await ExpoDlnaPlayerModule.seek(position);
  } catch (error) {
    console.error('[Expo DLNA Player] 跳转失败:', error);
    throw error;
  }
}

/**
 * 设置音量
 * @param volume 音量（0-100）
 */
export async function setVolume(volume: number): Promise<void> {
  try {
    return await ExpoDlnaPlayerModule.setVolume(volume);
  } catch (error) {
    console.error('[Expo DLNA Player] 设置音量失败:', error);
    throw error;
  }
}

/**
 * 获取播放状态
 * @returns 播放状态对象
 */
export async function getPlaybackStatus(): Promise<any> {
  try {
    return await ExpoDlnaPlayerModule.getPlaybackStatus();
  } catch (error) {
    console.error('[Expo DLNA Player] 获取播放状态失败:', error);
    throw error;
  }
}

/**
 * 设置播放速率
 * @param rate 播放速率（0.5-2.0之间）
 */
export async function setPlaybackRate(rate: number): Promise<void> {
  if (!ExpoDlnaPlayerModule.setRate) {
    console.warn('[Expo DLNA Player] 当前平台不支持设置播放速率');
    return;
  }
  return await ExpoDlnaPlayerModule.setRate(rate);
}

/**
 * 设置静音状态
 * @param muted 是否静音
 */
export async function setMuted(muted: boolean): Promise<void> {
  if (!ExpoDlnaPlayerModule.setMuted) {
    console.warn('[Expo DLNA Player] 当前平台不支持设置静音');
    return;
  }
  return await ExpoDlnaPlayerModule.setMuted(muted);
}

/**
 * 获取媒体缓冲状态
 * @returns 返回包含缓冲状态的对象
 */
export async function getBufferingStatus(): Promise<object | null> {
  if (!ExpoDlnaPlayerModule.getBufferingStatus) {
    console.warn('[Expo DLNA Player] 当前平台不支持获取缓冲状态');
    return null;
  }
  return await ExpoDlnaPlayerModule.getBufferingStatus();
}

/**
 * 检查当前设备是否支持Miracast投屏功能（仅Android可用）
 * @returns 是否支持Miracast
 */
export async function isProjectionSupported(): Promise<boolean> {
  if (!ExpoDlnaPlayerModule.isProjectionSupported) {
    console.warn('[Expo DLNA Player] 当前平台不支持Miracast');
    return false;
  }
  try {
    return await ExpoDlnaPlayerModule.isProjectionSupported();
  } catch (error) {
    console.error('[Expo DLNA Player] 检查Miracast支持失败:', error);
    return false;
  }
}

/**
 * 开始Miracast投屏（仅Android可用）
 * @param deviceId 设备ID
 * @param mode 投屏模式，可选值: "SCREEN_MIRRORING"(默认) 或 "VIDEO_ONLY"
 * @returns 是否成功启动投屏
 */
export async function startProjection(deviceId: string, mode?: string): Promise<boolean> {
  if (!ExpoDlnaPlayerModule.startProjection) {
    console.warn('[Expo DLNA Player] 当前平台不支持Miracast');
    return false;
  }
  try {
    return await ExpoDlnaPlayerModule.startProjection(deviceId, mode);
  } catch (error) {
    console.error('[Expo DLNA Player] 启动Miracast投屏失败:', error);
    return false;
  }
}

/**
 * 停止Miracast投屏（仅Android可用）
 */
export async function stopProjection(): Promise<boolean> {
  if (!ExpoDlnaPlayerModule.stopProjection) {
    console.warn('[Expo DLNA Player] 当前平台不支持Miracast');
    return false;
  }
  try {
    await ExpoDlnaPlayerModule.stopProjection();
    return true;
  } catch (error) {
    console.error('[Expo DLNA Player] 停止Miracast投屏失败:', error);
    return false;
  }
}

// 导出核心模块功能
export const ExpoDlnaPlayer = {
  // 设备发现和管理
  startDiscovery: ExpoDlnaPlayerModule.startDiscovery,
  stopDiscovery: ExpoDlnaPlayerModule.stopDiscovery,
  getDevices: ExpoDlnaPlayerModule.getDevices as () => Promise<DeviceInfo[]>,
  
  // 连接管理
  connectToDevice: ExpoDlnaPlayerModule.connectToDevice,
  disconnectFromDevice: ExpoDlnaPlayerModule.disconnectFromDevice,
  isConnected: ExpoDlnaPlayerModule.isConnected,
  getConnectedDevice: ExpoDlnaPlayerModule.getConnectedDevice as () => Promise<DeviceInfo | null>,
  
  // 播放控制
  play: ExpoDlnaPlayerModule.play,
  pause: ExpoDlnaPlayerModule.pause,
  resume: ExpoDlnaPlayerModule.resume,
  stop: ExpoDlnaPlayerModule.stop,
  seek: ExpoDlnaPlayerModule.seek,
  setVolume: ExpoDlnaPlayerModule.setVolume,
  setRate: ExpoDlnaPlayerModule.setRate,
  setMuted: ExpoDlnaPlayerModule.setMuted,
  
  // 状态查询
  getPlaybackStatus: ExpoDlnaPlayerModule.getPlaybackStatus as () => Promise<PlaybackStatus>,
  getBufferingStatus: ExpoDlnaPlayerModule.getBufferingStatus,
  
  // 事件监听
  addPlaybackStatusListener: (listener: (status: PlaybackStatus) => void) => 
    ExpoDlnaPlayerModule.addListener('onPlaybackStatusChanged', listener),
  addConnectionListener: (listener: (event: { deviceId: string, connected: boolean }) => void) => 
    ExpoDlnaPlayerModule.addListener('onConnectionChanged', listener),
  addErrorListener: (listener: (error: { code: string, message: string }) => void) => 
    ExpoDlnaPlayerModule.addListener('onError', listener),
};

export default ExpoDlnaPlayer;
