/**
 * 自适应布局组件
 * 支持主内容区 + 侧边栏布局，根据屏幕宽度自动调整侧边栏显示/隐藏
 * 支持移动端抽屉式侧边栏
 */

import React, { useState, useCallback, useEffect } from 'react';
import {
  View,
  StyleProp,
  ViewStyle,
  StyleSheet,
  Animated,
  TouchableOpacity,
  Modal,
  Pressable,
  Dimensions,
} from 'react-native';
import {
  useResponsive,
  useBreakpointGTE,
  FineBreakpointKey,
} from '../../hooks/useResponsive';

export interface AdaptiveLayoutProps {
  /** 主内容区 */
  children: React.ReactNode;
  /** 侧边栏内容 */
  sidebar?: React.ReactNode;
  /** 自定义头部 */
  header?: React.ReactNode;
  /** 自定义底部 */
  footer?: React.ReactNode;
  /** 布局样式 */
  style?: StyleProp<ViewStyle>;
  /** 主内容区样式 */
  contentStyle?: StyleProp<ViewStyle>;
  /** 侧边栏样式 */
  sidebarStyle?: StyleProp<ViewStyle>;
  /** 侧边栏宽度（桌面端） */
  sidebarWidth?: number;
  /** 移动端抽屉宽度 */
  drawerWidth?: number;
  /** 显示侧边栏的断点 */
  showSidebarBreakpoint?: FineBreakpointKey;
  /** 侧边栏位置 */
  sidebarPosition?: 'left' | 'right';
  /** 是否强制显示侧边栏（覆盖响应式逻辑） */
  forceShowSidebar?: boolean;
  /** 是否强制隐藏侧边栏（覆盖响应式逻辑） */
  forceHideSidebar?: boolean;
  /** 移动端抽屉是否打开（受控模式） */
  drawerOpen?: boolean;
  /** 移动端抽屉状态变化回调 */
  onDrawerOpenChange?: (open: boolean) => void;
  /** 渲染移动端抽屉触发按钮 */
  renderDrawerTrigger?: (props: { onPress: () => void; isOpen: boolean }) => React.ReactNode;
  /** 抽屉遮罩层颜色 */
  overlayColor?: string;
  /** 抽屉动画时长（毫秒） */
  animationDuration?: number;
}

/**
 * 自适应布局组件
 * 
 * 支持主内容区 + 侧边栏布局，根据屏幕宽度自动调整：
 * - 桌面端：并排显示侧边栏
 * - 移动端：侧边栏变为抽屉式，通过按钮触发
 * 
 * @example
 * // 基础用法
 * <AdaptiveLayout
 *   sidebar={<SidebarContent />}
 *   sidebarWidth={280}
 * >
 *   <MainContent />
 * </AdaptiveLayout>
 * 
 * @example
 * // 自定义断点和抽屉宽度
 * <AdaptiveLayout
 *   sidebar={<SidebarContent />}
 *   showSidebarBreakpoint="xl"
 *   sidebarWidth={320}
 *   drawerWidth={280}
 *   sidebarPosition="right"
 * >
 *   <MainContent />
 * </AdaptiveLayout>
 * 
 * @example
 * // 受控模式
 * const [drawerOpen, setDrawerOpen] = useState(false);
 * 
 * <AdaptiveLayout
 *   sidebar={<SidebarContent />}
 *   drawerOpen={drawerOpen}
 *   onDrawerOpenChange={setDrawerOpen}
 *   renderDrawerTrigger={({ onPress, isOpen }) => (
 *     <Button onPress={onPress}>
 *       {isOpen ? '关闭' : '菜单'}
 *     </Button>
 *   )}
 * >
 *   <MainContent />
 * </AdaptiveLayout>
 */
export function AdaptiveLayout({
  children,
  sidebar,
  header,
  footer,
  style,
  contentStyle,
  sidebarStyle,
  sidebarWidth = 280,
  drawerWidth = 280,
  showSidebarBreakpoint = 'lg',
  sidebarPosition = 'left',
  forceShowSidebar,
  forceHideSidebar,
  drawerOpen: controlledDrawerOpen,
  onDrawerOpenChange,
  renderDrawerTrigger,
  overlayColor = 'rgba(0, 0, 0, 0.5)',
  animationDuration = 300,
}: AdaptiveLayoutProps) {
  const { width, isMobile } = useResponsive();
  const shouldShowSidebar = useBreakpointGTE(showSidebarBreakpoint);
  
  // 内部抽屉状态（非受控模式）
  const [internalDrawerOpen, setInternalDrawerOpen] = useState(false);
  
  // 动画值
  const [slideAnim] = useState(new Animated.Value(0));
  const [fadeAnim] = useState(new Animated.Value(0));
  
  // 确定最终抽屉状态
  const isDrawerOpen = controlledDrawerOpen ?? internalDrawerOpen;
  const setDrawerOpen = useCallback((open: boolean) => {
    if (onDrawerOpenChange) {
      onDrawerOpenChange(open);
    } else {
      setInternalDrawerOpen(open);
    }
  }, [onDrawerOpenChange]);
  
  // 切换抽屉状态
  const toggleDrawer = useCallback(() => {
    setDrawerOpen(!isDrawerOpen);
  }, [isDrawerOpen, setDrawerOpen]);
  
  // 关闭抽屉
  const closeDrawer = useCallback(() => {
    setDrawerOpen(false);
  }, [setDrawerOpen]);
  
  // 抽屉动画
  useEffect(() => {
    if (isDrawerOpen) {
      Animated.parallel([
        Animated.timing(slideAnim, {
          toValue: 1,
          duration: animationDuration,
          useNativeDriver: true,
        }),
        Animated.timing(fadeAnim, {
          toValue: 1,
          duration: animationDuration,
          useNativeDriver: true,
        }),
      ]).start();
    } else {
      Animated.parallel([
        Animated.timing(slideAnim, {
          toValue: 0,
          duration: animationDuration,
          useNativeDriver: true,
        }),
        Animated.timing(fadeAnim, {
          toValue: 0,
          duration: animationDuration,
          useNativeDriver: true,
        }),
      ]).start();
    }
  }, [isDrawerOpen, slideAnim, fadeAnim, animationDuration]);
  
  // 计算侧边栏是否应该显示
  const isSidebarVisible = forceShowSidebar ?? (shouldShowSidebar && !forceHideSidebar);
  const isDrawerMode = !isSidebarVisible && !!sidebar;
  
  // 抽屉滑动动画
  const drawerTranslateX = slideAnim.interpolate({
    inputRange: [0, 1],
    outputRange: [
      sidebarPosition === 'left' ? -drawerWidth : drawerWidth,
      0,
    ],
  });
  
  // 渲染桌面端侧边栏
  const renderDesktopSidebar = () => {
    if (!sidebar || !isSidebarVisible) return null;
    
    return (
      <View
        style={[
          styles.sidebar,
          {
            width: sidebarWidth,
            [sidebarPosition === 'left' ? 'marginRight' : 'marginLeft']: 16,
          },
          sidebarStyle,
        ]}
      >
        {sidebar}
      </View>
    );
  };
  
  // 渲染移动端抽屉
  const renderMobileDrawer = () => {
    if (!sidebar || !isDrawerMode) return null;
    
    return (
      <Modal
        visible={isDrawerOpen}
        transparent
        animationType="none"
        onRequestClose={closeDrawer}
      >
        <View style={styles.modalContainer}>
          {/* 遮罩层 */}
          <TouchableOpacity
            style={styles.overlayTouchable}
            activeOpacity={1}
            onPress={closeDrawer}
          >
            <Animated.View
              style={[
                styles.overlay,
                { backgroundColor: overlayColor, opacity: fadeAnim },
              ]}
            />
          </TouchableOpacity>
          
          {/* 抽屉内容 */}
          <Animated.View
            style={[
              styles.drawer,
              {
                width: drawerWidth,
                [sidebarPosition]: 0,
                transform: [{ translateX: drawerTranslateX }],
              },
              sidebarStyle,
            ]}
          >
            {sidebar}
          </Animated.View>
        </View>
      </Modal>
    );
  };
  
  // 渲染抽屉触发按钮
  const renderTrigger = () => {
    if (!isDrawerMode || !renderDrawerTrigger) return null;
    
    return renderDrawerTrigger({
      onPress: toggleDrawer,
      isOpen: isDrawerOpen,
    });
  };
  
  return (
    <View style={[styles.container, style]}>
      {/* 头部 */}
      {header && (
        <View style={styles.header}>
          {header}
        </View>
      )}
      
      {/* 主布局区域 */}
      <View style={styles.main}>
        {/* 左侧布局 */}
        {sidebarPosition === 'left' && renderDesktopSidebar()}
        
        {/* 主内容区 */}
        <View style={[styles.content, contentStyle]}>
          {/* 抽屉触发按钮（仅在移动端抽屉模式显示） */}
          {renderTrigger()}
          {children}
        </View>
        
        {/* 右侧布局 */}
        {sidebarPosition === 'right' && renderDesktopSidebar()}
      </View>
      
      {/* 移动端抽屉 */}
      {renderMobileDrawer()}
      
      {/* 底部 */}
      {footer && (
        <View style={styles.footer}>
          {footer}
        </View>
      )}
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    width: '100%',
  },
  header: {
    width: '100%',
  },
  main: {
    flex: 1,
    flexDirection: 'row',
    width: '100%',
  },
  content: {
    flex: 1,
    minWidth: 0, // 防止 flex item 溢出
  },
  sidebar: {
    flexShrink: 0,
  },
  footer: {
    width: '100%',
  },
  modalContainer: {
    flex: 1,
    flexDirection: 'row',
  },
  overlayTouchable: {
    ...StyleSheet.absoluteFillObject,
  },
  overlay: {
    flex: 1,
  },
  drawer: {
    position: 'absolute',
    top: 0,
    bottom: 0,
    backgroundColor: '#fff',
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 0 },
    shadowOpacity: 0.25,
    shadowRadius: 8,
    elevation: 16,
  },
});

/**
 * 简化的侧边栏布局组件
 * 仅包含主内容和侧边栏，无头部底部
 */
export interface SidebarLayoutProps {
  children: React.ReactNode;
  sidebar: React.ReactNode;
  style?: StyleProp<ViewStyle>;
  contentStyle?: StyleProp<ViewStyle>;
  sidebarStyle?: StyleProp<ViewStyle>;
  sidebarWidth?: number;
  showSidebarBreakpoint?: FineBreakpointKey;
  sidebarPosition?: 'left' | 'right';
}

export function SidebarLayout({
  children,
  sidebar,
  style,
  contentStyle,
  sidebarStyle,
  sidebarWidth = 280,
  showSidebarBreakpoint = 'lg',
  sidebarPosition = 'left',
}: SidebarLayoutProps) {
  return (
    <AdaptiveLayout
      sidebar={sidebar}
      style={style}
      contentStyle={contentStyle}
      sidebarStyle={sidebarStyle}
      sidebarWidth={sidebarWidth}
      showSidebarBreakpoint={showSidebarBreakpoint}
      sidebarPosition={sidebarPosition}
    >
      {children}
    </AdaptiveLayout>
  );
}

export default AdaptiveLayout;
