/**
 * @file 表格的方式显示只读信息，比如产品详情
 */

import React from 'react';
import { Renderer, RendererProps } from '../factory';
import { BaseSchema, SchemaExpression, SchemaObject, SchemaTpl } from '../Schema';
import { resolveVariableAndFilter } from '../utils/tpl-builtin';
import { visibilityFilter, isMobile } from '../utils/helper';
import throttle from 'lodash/throttle'; // Aug
import { filter } from '../utils/tpl';

export type PropertyItemProps = {
  /**
   * 属性名
   */
  label?: SchemaTpl;

  /**
   * 属性值
   */
  content?: SchemaTpl;

  /**
   * 配置是否显示，如果不显示，后续的节点会补上来
   */
  visibleOn?: SchemaExpression;

  /**
   * 配置是否显示，如果不显示，后续的节点会补上来
   */
  hiddenOn?: SchemaExpression;

  /**
   * 跨几列
   */
  span?: number;

  /**
   * 配置过长是否需要隐藏
   */
  ellipsis?: boolean;

  /**
   * 配置图片压缩的宽度
   */
  pressWidth?: number;
  mode?: 'table' | 'simple';
  inheritWidth?: boolean;//property下的宽度需要继承，否则表格宽度异常
  classNameExpr?: string;
};

export type PropertyItem = PropertyItemProps & SchemaObject;

/**
 * Property 属性列表
 * 文档：https://baidu.gitee.io/amis/docs/components/property
 */
export interface PropertySchema extends BaseSchema {
  /**
   * 指定为 property 展示类型
   */
  type: 'property';

  /**
   * 标题
   */
  title?: string;

  /**
   * 一共几列
   */
  column?: number;

  /**
   * 显示模式
   */
  mode?: 'table' | 'simple';

  /**
   * 每个 property 的设置
   */
  items: Array<PropertyItem>;

  /**
   * 自定义样式
   */
  style?: {
    [propName: string]: any;
  };

  /**
   * 标题样式
   */
  titleStyle?: {
    [propName: string]: any;
  };

  /**
   * 自定义样式
   */
  labelStyle?: {
    [propName: string]: any;
  };

  separator?: string;

  /**
   * 自定义样式
   */
  contentStyle?: {
    [propName: string]: any;
  };
}

export interface PropertyProps
  extends RendererProps,
  Omit<PropertySchema, 'type' | 'className'> { }

interface PropertyContent {
  label: any;
  content: any;
  span: number;
  ellipsis?: boolean; //Aug
  mode?: 'table' | 'simple';
  remark?: string;
  inheritWidth?: boolean;//property下的宽度需要继承，否则表格宽度异常
  classNameExpr?: string
}

export default class Property extends React.Component<PropertyProps, any> {
  /**
   * 算好每行的分布情况，方便后续渲染
   */
  prepareRows() {
    const { items, source, data, useMobileUI } = this.props;
    // Aug 移动端适配 始终一行
    let { column = 3 } = this.props;
    if (useMobileUI && isMobile()) {
      column = 1
    }
    const propertyItems =
      (items
        ? items
        : (resolveVariableAndFilter(
          source,
          data,
          '| raw'
        ) as Array<PropertyItem>)) || [];

    const rows: PropertyContent[][] = [];

    let row: PropertyContent[] = [];
    let columnLeft = column;
    let index = 0;
    const filteredItems = visibilityFilter(propertyItems, data);

    for (const item of filteredItems) {
      index = index + 1;
      const span = Math.min(item.span || 1, column);
      columnLeft = columnLeft - span;
      const rowItem = {
        label: item.label,
        content: item.content,
        span: span,
        mode: item.mode,
        remark: item.remark,
        inheritWidth: item?.inheritWidth,
        classNameExpr: item?.classNameExpr
      };

      // 如果还能放得下就放这一行
      if (columnLeft >= 0) {
        row.push(rowItem);
      } else {
        rows.push(row);
        columnLeft = column - span;
        row = [rowItem];
      }

      // 最后一行将最后的数据 push
      if (index === filteredItems.length) {
        rows.push(row);
      }
    }
    return rows;
  }

  renderRow(rows: PropertyContent[][]) {
    const {
      render,
      contentStyle,
      labelStyle,
      mode = 'table',
      classnames: cx, //Aug
      column = 3, //Aug
      env,
      popOverContainer
    } = this.props;
    return rows.map((row, key) => {
       //判断是否有符合条件撑满图片
      const fillImage = row.find(col => col.content.type === 'lion-upload' && col.span == 1 && key == rows.length - 1)
      return (
        <div key={key} className={cx('Property-wrapper-content-row')} style={{ height: !!fillImage ? '100%' : undefined}}>
          {row.map((property, index) => {
            const itemMode = (property.content?.type === 'input-table-field' && property.content?.tableLayout === 'vertical') || property.content?.type == 'matrix-checkboxes' ? 'simple' : property.content?.type === 'progress' ? mode : property.mode || mode
            const { ellipsis = true, remark } = property //Aug
            const isLastFillCell = (property.span == 1 && row.length != column && property.label === row[row.length - 1]?.label)
            const fillCell = property.content.type === 'lion-upload' && property.span == 1 && key == rows.length - 1
            const labelSpan = (isLastFillCell ? column - index : property.span) / column;
            return itemMode === 'table' ? (
              <div style={{width: ((isLastFillCell ? column - index : property.span) / column * 100) + '%', flex: isLastFillCell ? '1' : ''}} key={`item-${index}`} className={cx('Property-wrapper-content-row-table-item')}>
                {!(property.content?.tableLayout === 'horizontal' && !isMobile()) &&
                  <div style={{ width: (0.1 / labelSpan * 100) + '%', minWidth: '120px' }} className='property-formitem-label'>
                    <div
                      className={cx('cell', { 'ellipsis': ellipsis })}
                      style={Object.assign({ width: '100%', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }, labelStyle)}
                    >
                      {render('label', property.label)}
                    </div>
                    {remark && render('label-remark', {
                      type: 'remark',
                      icon: property.content?.icon,
                      tooltip: remark,
                      style: { display: 'flex' },
                      container: popOverContainer ? popOverContainer : env.getModalContainer ? env.getModalContainer : undefined
                    })}
                  </div>}
                <div
                  style={{ padding: property.content?.type === 'input-table-field' ? 0 : undefined, height: fillCell ? '100%' : undefined, width: property.content?.tableLayout === 'horizontal' && !isMobile() ? '100%' : 'unset'}}
                  className={(property.classNameExpr ? filter(property.classNameExpr, this.props.data) : '') + ' property-formitem-value'}
                >
                  {property.content?.tableLayout === 'horizontal' && !isMobile() ? <div className='fieldTable-block'></div> : null}
                  <div className={cx('cell', { 'ellipsis-cell': ellipsis }, isLastFillCell && 'full-cell')}
                    // 减去label 以及 th td > border的宽度
                    style={Object.assign({
                      height: fillCell ? '97%' : undefined,
                    },
                      contentStyle,
                      property.content?.tableLayout === 'horizontal' && !isMobile() ? { padding: 0 } : {}
                    )}>
                    {render('content', property.content, {
                      data: this.props.data,
                      key: `${property.content.name}-${property.content.type}-${index}`,
                      labelName: property.label,
                      isProperty: true,
                      fillCell,
                      fieldTableRemark: property.remark
                    })}
                  </div>
                </div>
              </div>
            ) : (
              <div
                style={contentStyle}
                key={`item-${index}`}
                className={cx('Property-wrapper-content-row-normal-item')}
              >
                <div className='fieldTable-block'></div>
                {render('content', property.content, { labelName: property.label, isProperty: true, span: column, fieldTableRemark: property.remark })}
              </div>
            );
          })}
        </div>
      );
    });
  }

  render() {
    const {
      style,
      title,
      classnames: cx,
      className,
      titleStyle,
      mode = 'table',
      items = []
    } = this.props;
    // 如果有items数据，但是又配置了所有选项隐藏，那么就直接返回null, 否则会出现空的div样式污染问题
    const hasItemButAllHidden = items.every((item) => item['hidden']);
    if (hasItemButAllHidden) {
      return null;
    }
    const rows = this.prepareRows();
    //判断是否有符合条件撑满图片
    const fillImage = rows.find((row, key) => row.find(col => col.content.type === 'lion-upload' && col.span == 1 && key == rows.length - 1));
    return (
      <div
        className={cx('Property', `Property--${mode}`, className)}
        style={{ ...style, height: !!fillImage ? '100%' : undefined }}
      >
        <div className={cx('Property-wrapper')} style={{ height: !!fillImage ? '100%' : undefined}}>
          {title ? <div className={cx('Property-wrapper-title')} style={titleStyle}></div> : null}
          <div className={cx('Property-wrapper-content')} style={{ height: !!fillImage ? '100%' : undefined}}>
            {this.renderRow(rows)}
          </div>
        </div>
      </div>
    );
  }
}

@Renderer({
  type: 'property'
})
export class PropertyRenderer extends Property { }
