import { _decorator, Component, Enum, instantiate, math, Node, Prefab, UITransform } from 'cc';
import { YXCollectionView, YXEdgeInsets, YXFlowLayout, YXIndexPath } from '../lib';
const { ccclass, property } = _decorator;

/**
 * 节点对齐方式枚举
 */
enum _yx_table_view_item_alignment {
    /**
     * cell 节点紧靠列表左边
     */
    LEFT,
    /**
     * cell 节点相对列表水平居中
     */
    CENTER,
    /**
     * cell 节点紧靠列表右边
     */
    RIGHT,
}
Enum(_yx_table_view_item_alignment)

/**
 * 节点大小模式枚举
 */
enum _yx_table_view_item_size_mode {
    /**
     * 使用预制体节点大小
     */
    USE_PREFAB_SIZE,
    /**
     * 自定义节点大小
     */
    CUSTOM,
}
Enum(_yx_table_view_item_size_mode)

/**
 * 基于 YXCollectionView 和 YXFlowLayout 封装的一个简单的 TableView
 * 请注意，这个组件更多是为了演示如何基于 YXCollectionView 来实现自己需要的列表组件，并非完整的功能组件
 * 如果这个组件符合业务的话可以直接拿来用，如果满足不了需求，可以根据实际业务，选择开放更多的配置或者直接使用 YXCollectionView
 * 
 * ---
 * 此组件说明
 * - 仅支持编辑器配置
 * - 仅支持垂直方向滚动
 * - 仅支持单类型 cell 节点样式
 * - 仅支持固定的 cell 节点大小
 * - 支持 cell 节点相对于列表的对齐方式，默认居中对齐
 */
@ccclass('YXTableView')
export class YXTableView<T = any> extends Component {

    static Alignment = _yx_table_view_item_alignment

    @property({ tooltip: `cell 节点预制体`, type: Prefab, visible: true })
    private cellPrefab: Prefab = null

    @property({ tooltip: `如何配置 cell 节点大小\nUSE_PREFAB_SIZE: 自动读取预制体大小\nCUSTOM: 自定义节点大小`, type: _yx_table_view_item_size_mode, visible: true })
    private itemSizeMode: _yx_table_view_item_size_mode = _yx_table_view_item_size_mode.CUSTOM

    @property({
        tooltip: `cell 节点大小`, visible: function (this) {
            return (this.itemSizeMode == _yx_table_view_item_size_mode.CUSTOM)
        }
    })
    private itemSize: math.Size = new math.Size(100, 100)

    @property({ tooltip: `cell 节点对齐方式`, type: _yx_table_view_item_alignment, visible: true })
    private alignment: _yx_table_view_item_alignment = _yx_table_view_item_alignment.CENTER

    @property({ tooltip: `cell 节点之间间距`, visible: true })
    private spacing: number = 0

    @property({ tooltip: `顶部最大偏移距离`, visible: true })
    private top: number = 0

    @property({ tooltip: `底部最大偏移距离`, visible: true })
    private bottom: number = 0

    /**
     * 列表组件
     */
    private collectionView: YXCollectionView = null

    /**
     * 更新列表数据
     * @param data 列表绑定的数据源
     */
    setData(data: T[]) {
        this.data = data
        this.reloadCollectionViewIfNeeds()
    }
    private data: T[] = null

    /**
     * 更新 cell 节点
     * @param call 
     */
    onCellDisplay(call: typeof this.updateCellCall) {
        this.updateCellCall = call
        this.reloadCollectionViewIfNeeds()
    }
    private updateCellCall: (cell: Node, itemData: T, index: number) => void = null

    /**
     * 滚动到指定节点位置
     * @param idx 
     */
    scrollTo(idx: number) {
        let indexPath = new YXIndexPath(0, idx)
        this.collectionView.scrollTo(indexPath)
    }

    /**
     * 生命周期方法
     */
    protected onLoad(): void {
        this.collectionView = this.node.getComponent(YXCollectionView) || this.node.addComponent(YXCollectionView)

        this.collectionView.register(`cell`, () => instantiate(this.cellPrefab))
        this.collectionView.scrollDirection = YXCollectionView.ScrollDirection.VERTICAL
        this.collectionView.numberOfItems = () => this.data.length
        this.collectionView.onCellDisplay = (cell, indexPath, collectionView) => {
            if (this.updateCellCall) {
                this.updateCellCall(cell, this.data[indexPath.item], indexPath.item)
            }
        }

        let layout = new YXFlowLayout()
        let itemSize = this.itemSize
        if (this.itemSizeMode == _yx_table_view_item_size_mode.USE_PREFAB_SIZE) {
            itemSize = instantiate(this.cellPrefab).getComponent(UITransform).contentSize
        }
        layout.itemSize = itemSize
        let left = 0
        if (this.alignment == YXTableView.Alignment.LEFT) { left = 0 }
        if (this.alignment == YXTableView.Alignment.CENTER) { left = (this.collectionView.scrollView.view.width - itemSize.width) * 0.5 }
        if (this.alignment == YXTableView.Alignment.RIGHT) { left = (this.collectionView.scrollView.view.width - itemSize.width) * 1 }
        layout.sectionInset = new YXEdgeInsets(this.top, left, this.bottom, 0)
        layout.verticalSpacing = this.spacing
        this.collectionView.layout = layout
    }

    protected onDestroy(): void {
        this.data = []
    }

    private reloadCollectionViewIfNeeds() {
        // `数据源` 配置好后才去更新列表，没配置好的话更新没有意义
        if (this.data == null) {
            return
        }
        this.collectionView.reloadData()
    }
}

