import { View } from '@tarojs/components';
import { callable, classNames, deepGet } from 'mixlea-utils-js';

import { Header } from './header';
import type { MlBaseFormListColumn, MlBaseFormListData, MlBaseFormListProps } from './types';
import { Footer } from './footer';
import { Body } from './body';
import { safeGetRowKey } from './tools/safe-get-row-key';
import { safeGetCellContent } from './tools/safe-get-cell-content';
import { FormItem } from './form-item';
import { mergeElementProps } from './tools/merge-element-props';

export type { MlBaseFormListProps, MlBaseFormListColumn, MlBaseFormListData };

export { mergeElementProps };

export function MlBaseFromList(props: MlBaseFormListProps) {
  return (
    <View
      className={classNames('flex flex-col', props.className)}
      style={{
        // @ts-expect-error CSS Vars
        '--grid-col-number': callable(props.cols, { columns: props.columns }) ?? 1,
      }}
    >
      <Header {...props} />
      <Body formListData={props.formListData}>
        <View className="flex flex-col gap-y-base">
          {props.formListData.map((row, rowIndex) => {
            const rowKey = safeGetRowKey(props.rowKeyField, row, rowIndex);

            return (
              <FormItem
                key={rowKey}
                rowHeightSize={props.rowHeightSize}
                columnTitleWordNumber={props.columnTitleWordNumber}
              >
                {props.columns.map((column, colIndex) => {
                  const cellValue = deepGet(props.formListData, column.field, undefined);

                  const cellProps = column.getCellProps?.(cellValue, props.formListData, { rowIndex, colIndex }) ?? {};
                  const headerProps =
                    column.getHeaderProps?.(cellValue, props.formListData, { rowIndex, colIndex }) ?? {};
                  const contentProps =
                    column.getContentProps?.(cellValue, props.formListData, { rowIndex, colIndex }) ?? {};

                  const contentLeft = column.renderLeft?.(cellValue, row, rowIndex) ?? undefined;
                  const contentRight = column.renderRight?.(cellValue, row, rowIndex) ?? undefined;

                  const colSpanAll = callable(column.colSpanAll, {
                    cellValue,
                    row,
                    rowIndex,
                  });

                  return (
                    <View
                      key={column.field}
                      className={classNames(cellProps.className, 'form-cell flex', {
                        'col-span-full': colSpanAll,
                      })}
                    >
                      <View
                        {...headerProps}
                        style={headerProps.style}
                        className={classNames(headerProps.className, 'form-cell-header h-full')}
                      >
                        {column.title}
                      </View>
                      {contentLeft && <View> {contentLeft}</View>}
                      <View
                        {...contentProps}
                        style={contentProps.style}
                        className={classNames(contentProps.className, 'form-cell-content h-full flex-1 min-w-0')}
                      >
                        {safeGetCellContent({
                          column,
                          cellValue,
                          row,
                          rowIndex,
                        })}
                      </View>
                      {contentRight && <View> {contentRight}</View>}
                    </View>
                  );
                })}
              </FormItem>
            );
          })}
        </View>
      </Body>
      <Footer {...props} />
    </View>
  );
}
