import '@testing-library/jest-dom'

/* eslint-disable react/display-name */

// 设置环境变量
process.env.TARO_ENV = 'h5'
process.env.TARO_PLATFORM = 'web'
process.env.SUPPORT_TARO_POLYFILL = 'disabled'

// Mock Taro 组件
// eslint-disable-next-line react/display-name
jest.mock('@tarojs/components', () => {
  const React = require('react')
  const MockView = React.forwardRef((props: any, ref: any) => {
    const { children, ...restProps } = props
    return React.createElement('div', { ...restProps, ref }, children)
  })
  MockView.displayName = 'MockView'

  const MockScrollView = React.forwardRef((props: any, ref: any) => {
    const {
      children,
      onScroll,
      onTouchStart,
      onScrollEnd,
      // eslint-disable-next-line @typescript-eslint/no-unused-vars
      scrollY,
      // eslint-disable-next-line @typescript-eslint/no-unused-vars
      showScrollbar,
      // eslint-disable-next-line @typescript-eslint/no-unused-vars
      scrollTop,
      // eslint-disable-next-line @typescript-eslint/no-unused-vars
      scrollWithAnimation,
      ...restProps
    } = props
    return React.createElement('div', {
      ...restProps,
      ref,
      onScroll: (e: any) => {
        if (onScroll) onScroll(e)
      },
      onTouchStart: (e: any) => {
        if (onTouchStart) onTouchStart(e)
      },
      onTouchEnd: () => {
        if (onScrollEnd) onScrollEnd()
      },
      style: {
        overflow: 'auto',
        height: '200px',
        ...restProps.style
      }
    }, children)
  })
  MockScrollView.displayName = 'MockScrollView'

  return {
    View: MockView,
    ScrollView: MockScrollView,
    Text: (() => {
      const MockText = React.forwardRef((props: any, ref: any) => {
        const { children, ...restProps } = props
        return React.createElement('span', { ...restProps, ref }, children)
      })
      MockText.displayName = 'MockText'
      return MockText
    })(),
    Button: (() => {
      const MockButton = React.forwardRef((props: any, ref: any) => {
        const { children, ...restProps } = props
        return React.createElement('button', { ...restProps, ref }, children)
      })
      MockButton.displayName = 'MockButton'
      return MockButton
    })(),
    Input: (() => {
      const MockInput = React.forwardRef((props: any, ref: any) => {
        const { ...restProps } = props
        return React.createElement('input', { ...restProps, ref })
      })
      MockInput.displayName = 'MockInput'
      return MockInput
    })(),
    Textarea: (() => {
      const MockTextarea = React.forwardRef((props: any, ref: any) => {
        const { children, ...restProps } = props
        return React.createElement('textarea', { ...restProps, ref }, children)
      })
      MockTextarea.displayName = 'MockTextarea'
      return MockTextarea
    })(),
    Image: (() => {
      const MockImage = React.forwardRef((props: any, ref: any) => {
        const { ...restProps } = props
        return React.createElement('img', { ...restProps, ref })
      })
      MockImage.displayName = 'MockImage'
      return MockImage
    })(),
    Form: (() => {
      const MockForm = React.forwardRef((props: any, ref: any) => {
        const { children, ...restProps } = props
        return React.createElement('form', { ...restProps, ref }, children)
      })
      MockForm.displayName = 'MockForm'
      return MockForm
    })(),
    Label: (() => {
      const MockLabel = React.forwardRef((props: any, ref: any) => {
        const { children, ...restProps } = props
        return React.createElement('label', { ...restProps, ref }, children)
      })
      MockLabel.displayName = 'MockLabel'
      return MockLabel
    })(),
    Picker: (() => {
      const MockPicker = React.forwardRef((props: any, ref: any) => {
        const { children, ...restProps } = props
        return React.createElement('div', { ...restProps, ref }, children)
      })
      MockPicker.displayName = 'MockPicker'
      return MockPicker
    })(),
    Switch: (() => {
      const MockSwitch = React.forwardRef((props: any, ref: any) => {
        const { ...restProps } = props
        return React.createElement('input', { type: 'checkbox', ...restProps, ref })
      })
      MockSwitch.displayName = 'MockSwitch'
      return MockSwitch
    })(),
    Slider: (() => {
      const MockSlider = React.forwardRef((props: any, ref: any) => {
        const { ...restProps } = props
        return React.createElement('input', { type: 'range', ...restProps, ref })
      })
      MockSlider.displayName = 'MockSlider'
      return MockSlider
    })(),
    Radio: React.forwardRef((props: any, ref: any) => {
      const { children, ...restProps } = props
      return React.createElement('input', { type: 'radio', ...restProps, ref }, children)
    }),
    RadioGroup: React.forwardRef((props: any, ref: any) => {
      const { children, ...restProps } = props
      return React.createElement('div', { ...restProps, ref }, children)
    }),
    Checkbox: React.forwardRef((props: any, ref: any) => {
      const { children, ...restProps } = props
      return React.createElement('input', { type: 'checkbox', ...restProps, ref }, children)
    }),
    CheckboxGroup: React.forwardRef((props: any, ref: any) => {
      const { children, ...restProps } = props
      return React.createElement('div', { ...restProps, ref }, children)
    }),
    Progress: React.forwardRef((props: any, ref: any) => {
      const { ...restProps } = props
      return React.createElement('progress', { ...restProps, ref })
    }),
    RichText: React.forwardRef((props: any, ref: any) => {
      const { children, ...restProps } = props
      return React.createElement('div', { ...restProps, ref }, children)
    }),
    MovableArea: React.forwardRef((props: any, ref: any) => {
      const { children, ...restProps } = props
      return React.createElement('div', { ...restProps, ref }, children)
    }),
    MovableView: React.forwardRef((props: any, ref: any) => {
      const { children, ...restProps } = props
      return React.createElement('div', { ...restProps, ref }, children)
    }),
    Swiper: React.forwardRef((props: any, ref: any) => {
      const { children, ...restProps } = props
      return React.createElement('div', { ...restProps, ref }, children)
    }),
    SwiperItem: React.forwardRef((props: any, ref: any) => {
      const { children, ...restProps } = props
      return React.createElement('div', { ...restProps, ref }, children)
    }),
    Navigator: React.forwardRef((props: any, ref: any) => {
      const { children, ...restProps } = props
      return React.createElement('a', { ...restProps, ref }, children)
    }),
    Audio: React.forwardRef((props: any, ref: any) => {
      const { ...restProps } = props
      return React.createElement('audio', { ...restProps, ref })
    }),
    Video: React.forwardRef((props: any, ref: any) => {
      const { children, ...restProps } = props
      return React.createElement('video', { ...restProps, ref }, children)
    }),
    Camera: React.forwardRef((props: any, ref: any) => {
      const { children, ...restProps } = props
      return React.createElement('div', { ...restProps, ref }, children)
    }),
    LivePlayer: React.forwardRef((props: any, ref: any) => {
      const { children, ...restProps } = props
      return React.createElement('div', { ...restProps, ref }, children)
    }),
    LivePusher: React.forwardRef((props: any, ref: any) => {
      const { children, ...restProps } = props
      return React.createElement('div', { ...restProps, ref }, children)
    }),
    Map: React.forwardRef((props: any, ref: any) => {
      const { children, ...restProps } = props
      return React.createElement('div', { ...restProps, ref }, children)
    }),
    Canvas: React.forwardRef((props: any, ref: any) => {
      const { children, ...restProps } = props
      return React.createElement('canvas', { ...restProps, ref }, children)
    }),
    OpenData: React.forwardRef((props: any, ref: any) => {
      const { children, ...restProps } = props
      return React.createElement('div', { ...restProps, ref }, children)
    }),
    WebView: React.forwardRef((props: any, ref: any) => {
      const { children, ...restProps } = props
      return React.createElement('iframe', { ...restProps, ref }, children)
    }),
    Ad: React.forwardRef((props: any, ref: any) => {
      const { children, ...restProps } = props
      return React.createElement('div', { ...restProps, ref }, children)
    }),
    OfficialAccount: React.forwardRef((props: any, ref: any) => {
      const { children, ...restProps } = props
      return React.createElement('div', { ...restProps, ref }, children)
    }),
    CoverView: React.forwardRef((props: any, ref: any) => {
      const { children, ...restProps } = props
      return React.createElement('div', { ...restProps, ref }, children)
    }),
    CoverImage: React.forwardRef((props: any, ref: any) => {
      const { ...restProps } = props
      return React.createElement('img', { ...restProps, ref })
    }),
    FunctionalPageNavigator: React.forwardRef((props: any, ref: any) => {
      const { children, ...restProps } = props
      return React.createElement('div', { ...restProps, ref }, children)
    }),
    AdContent: React.forwardRef((props: any, ref: any) => {
      const { children, ...restProps } = props
      return React.createElement('div', { ...restProps, ref }, children)
    }),
    MatchMedia: React.forwardRef((props: any, ref: any) => {
      const { children, ...restProps } = props
      return React.createElement('div', { ...restProps, ref }, children)
    }),
    PageContainer: React.forwardRef((props: any, ref: any) => {
      const { children, ...restProps } = props
      return React.createElement('div', { ...restProps, ref }, children)
    }),
    ShareElement: React.forwardRef((props: any, ref: any) => {
      const { children, ...restProps } = props
      return React.createElement('div', { ...restProps, ref }, children)
    }),
    KeyboardAccessory: React.forwardRef((props: any, ref: any) => {
      const { children, ...restProps } = props
      return React.createElement('div', { ...restProps, ref }, children)
    }),
    RootPortal: React.forwardRef((props: any, ref: any) => {
      const { children, ...restProps } = props
      return React.createElement('div', { ...restProps, ref }, children)
    }),
    PageMeta: React.forwardRef((props: any, ref: any) => {
      const { children, ...restProps } = props
      return React.createElement('div', { ...restProps, ref }, children)
    }),
    NavigationBar: React.forwardRef((props: any, ref: any) => {
      const { children, ...restProps } = props
      return React.createElement('div', { ...restProps, ref }, children)
    }),
    Block: React.forwardRef((props: any, ref: any) => {
      const { children, ...restProps } = props
      return React.createElement('div', { ...restProps, ref }, children)
    }),
    Import: React.forwardRef((props: any, ref: any) => {
      const { children, ...restProps } = props
      return React.createElement('div', { ...restProps, ref }, children)
    }),
    Include: React.forwardRef((props: any, ref: any) => {
      const { children, ...restProps } = props
      return React.createElement('div', { ...restProps, ref }, children)
    }),
    Template: React.forwardRef((props: any, ref: any) => {
      const { children, ...restProps } = props
      return React.createElement('div', { ...restProps, ref }, children)
    }),
    Slot: React.forwardRef((props: any, ref: any) => {
      const { children, ...restProps } = props
      return React.createElement('div', { ...restProps, ref }, children)
    }),
    NativeSlot: React.forwardRef((props: any, ref: any) => {
      const { children, ...restProps } = props
      return React.createElement('div', { ...restProps, ref }, children)
    }),
    CustomWrapper: React.forwardRef((props: any, ref: any) => {
      const { children, ...restProps } = props
      return React.createElement('div', { ...restProps, ref }, children)
    }),
    Editor: React.forwardRef((props: any, ref: any) => {
      const { children, ...restProps } = props
      return React.createElement('div', { ...restProps, ref }, children)
    }),
    VoipRoom: React.forwardRef((props: any, ref: any) => {
      const { children, ...restProps } = props
      return React.createElement('div', { ...restProps, ref }, children)
    }),
    AdCustom: React.forwardRef((props: any, ref: any) => {
      const { children, ...restProps } = props
      return React.createElement('div', { ...restProps, ref }, children)
    })
  }
})

// 模拟 MutationObserver
// @ts-ignore
global.MutationObserver = class {
  disconnect() {}
  observe(_element: any, _initObject: any) {}
  takeRecords() { return [] }
}

// 模拟 IntersectionObserver
// @ts-ignore
global.IntersectionObserver = class {
  constructor(fn: (args: any[]) => void) {
    setTimeout(() => {
      fn([{ isIntersecting: true }])
    }, 1000)
  }

  observe() {}
  unobserve() {}
  disconnect() {}
  takeRecords() { return [] }
  root: null = null
  rootMargin: string = ''
  thresholds: number[] = []
}

// 模拟 ResizeObserver
// @ts-ignore
global.ResizeObserver = class {
  observe() {}
  unobserve() {}
  disconnect() {}
}

// 模拟 matchMedia
Object.defineProperty(window, 'matchMedia', {
  writable: true,
  value: jest.fn().mockImplementation(query => ({
    matches: false,
    media: query,
    onchange: null,
    addListener: jest.fn(), // deprecated
    removeListener: jest.fn(), // deprecated
    addEventListener: jest.fn(),
    removeEventListener: jest.fn(),
    dispatchEvent: jest.fn(),
  })),
})

// 模拟 getComputedStyle
Object.defineProperty(window, 'getComputedStyle', {
  value: () => ({
    getPropertyValue: (prop: string) => {
      return {
        'font-size': '16px',
        'font-family': 'Arial',
        color: 'rgb(0, 0, 0)',
        'background-color': 'rgb(255, 255, 255)',
        width: '100px',
        height: '100px',
        top: '0px',
        left: '0px',
        right: '0px',
        bottom: '0px',
        x: '0px',
        y: '0px'
      }[prop] || ''
    }
  })
})

// 模拟 Element.prototype.getBoundingClientRect
Element.prototype.getBoundingClientRect = jest.fn(() => ({
  width: 100,
  height: 100,
  top: 0,
  left: 0,
  bottom: 100,
  right: 100,
  x: 0,
  y: 0,
  toJSON: () => ({
    width: 100,
    height: 100,
    top: 0,
    left: 0,
    bottom: 100,
    right: 100,
    x: 0,
    y: 0
  })
}))

// 静默 console.error 在测试中
const originalConsoleError = console.error
console.error = (...args: any[]) => {
  // 检查是否在测试环境中（通过 Jest 环境变量判断）
  const isTestEnv = process.env.JEST_WORKER_ID !== undefined ||
                    typeof jest !== 'undefined'

  // 在测试环境中静默错误输出，除非是重要错误
  if (isTestEnv && !args[0]?.includes?.('重要错误')) {
    return
  }
  originalConsoleError(...args)
}

// Mock 常用 UI 组件
jest.mock('@/components/ui/dialog', () => {
  const React = require('react')
  return {
    Dialog: ({ open, children }: any) => open ? React.createElement('div', { 'data-testid': 'dialog' }, children) : null,
    DialogContent: ({ children, className }: any) => React.createElement('div', { className }, children),
    DialogHeader: ({ children, className }: any) => React.createElement('div', { className }, children),
    DialogTitle: ({ children, className }: any) => React.createElement('div', { className }, children),
    DialogFooter: ({ children, className }: any) => React.createElement('div', { className }, children)
  }
})