import {
  FieldDataType,
  ModelType,
  I18N_T,
  ModelsFieldsTypeMap,
} from "@gadmin2/react-common";
import {
  TextField,
  DateField,
  FilterDropdown,
  ImageField,
  FileField,
  NumberField,
  BooleanField,
  EmailField,
  UrlField,
  ShowButton,
  TagField,
} from "@refinedev/antd";
import { CheckCircleTwoTone, CloseCircleTwoTone } from "@ant-design/icons";
import { FilterDropdownProps } from "antd/lib/table/interface";
import { Select, Table, Space, SelectProps } from "antd";
import {
  CrudSorting,
  CrudFilters,
  getDefaultSortOrder,
  getDefaultFilter,
  stringifyTableParams,
} from "@refinedev/core";
import { DefaultOptionType } from "antd/es/select";
import { ModelConfig } from "generated/types/config.types";

export function getTableParams(filters: Record<string, string> = {}) {
  return stringifyTableParams({
    pagination: { pageSize: 10, current: 1 },
    sorters: [],
    filters: Object.entries(filters).map(([field, value]) => ({
      field,
      operator: "eq",
      value,
    })),
  });
}

export function getTableColumn(
  col: FieldDataType,
  resourceName: string,
  t: I18N_T,
  model: ModelType,
  modelsEnum: Record<string, Record<string, string>>,
  modelsMap: ModelsFieldsTypeMap,
  tableConfig: ModelConfig["table"],
  sorter: CrudSorting | undefined,
  filters: CrudFilters | undefined,
  relationSelectProps: Record<
    string,
    SelectProps<
      {
        value: string;
        label: string;
      },
      DefaultOptionType
    >
  >
) {
  const { type: fieldType, args } = col.uiType.formItem;
  const fieldName = col.name;
  const props: any = {
    dataIndex: fieldName.includes(".") ? fieldName.split(".") : fieldName,
    key: fieldName,
    title: t(`resources.${resourceName}.fields.${fieldName}`, fieldName),
    render: (value: any) => <TextField value={value} />,
  };
  if (col.kind === "object" && !col.isList && !fieldName.includes(".")) {
    const entityName = model[fieldName]?.type || "";
    props.dataIndex = [fieldName, "id"];
    props.key = `${fieldName}.id`;
    props.title = t(
      `resources.${resourceName}.fields.${fieldName}`,
      t(`resources.${entityName.toLowerCase()}.name`, entityName)
    );
    props.render = (_: any, record: any) =>
      record?.[fieldName]?.id !== undefined ? (
        <ShowButton
          icon={false}
          type="link"
          size="small"
          resource={entityName.toLowerCase()}
          recordItemId={record[fieldName].id}
        >
          {
            record[fieldName][
              modelsMap[entityName]?.meta?.nameKeys?.[0] || "id"
            ]
          }
        </ShowButton>
      ) : null;
  } else if (fieldName.startsWith("_count.")) {
    const entityName = model[fieldName.split(".")[1]]?.type || "";
    props.title = t(
      `resources.${resourceName}.fields.${fieldName}`,
      "Count " + t(`resources.${entityName.toLowerCase()}.name`, entityName)
    );
  } else if (fieldType === "DateTime") {
    props.render = (value: any) => {
      return <DateField value={value} format="YYYY-MM-DD HH:mm:ss" />;
    };
  } else if (["Int", "BigInt", "Float", "Decimal"].includes(fieldType)) {
    props.render = (value: any) => {
      if (
        fieldName !== "id" &&
        value !== undefined &&
        value !== null &&
        !isNaN(value)
      ) {
        return <NumberField value={value ?? ""} />;
      } else {
        return <TextField value={value} />;
      }
    };
  } else if (fieldType === "Url") {
    props.render = (value: any) => {
      return <UrlField value={value} />;
    };
  } else if (fieldType === "Email") {
    props.render = (value: any) => {
      return <EmailField value={value} />;
    };
  } else if (fieldType === "Boolean") {
    props.render = (value: any) => {
      return (
        <BooleanField
          value={value}
          trueIcon={<CheckCircleTwoTone twoToneColor="#52c41a" />}
          falseIcon={<CloseCircleTwoTone twoToneColor="red" />}
        />
      );
    };
  } else if (fieldType === "Radio" || col.kind === "enum") {
    props.render = (value: any) => {
      return (
        <TagField
          value={t(
            `resources.${resourceName}.enums.${fieldName}.${value}`,
            value
          )}
        />
      );
    };
  } else if (fieldType === "CheckBox") {
    props.render = (value: any) => {
      return (
        <Space>
          {JSON.parse(value || "[]")?.map?.((v: string) => (
            <TagField
              value={t(`resources.${resourceName}.enums.${fieldName}.${v}`, v)}
            />
          ))}
        </Space>
      );
    };
  } else if (fieldType === "Select") {
    if (args.mode === "multiple") {
      props.render = (value: any) => {
        return (
          <Space>
            {JSON.parse(value || "[]")?.map?.((v: string) => (
              <TagField
                value={t(
                  `resources.${resourceName}.enums.${fieldName}.${v}`,
                  v
                )}
              />
            ))}
          </Space>
        );
      };
    } else {
      props.render = (value: any) => {
        return (
          <TagField
            value={t(
              `resources.${resourceName}.enums.${fieldName}.${value}`,
              value
            )}
          />
        );
      };
    }
  } else if (fieldType === "Image") {
    props.render = (value: any) => {
      return (
        <Space wrap>
          {JSON.parse(value || "[]")?.map?.((img: any) => (
            <ImageField
              key={img?.response?.name}
              value={img?.thumbUrl}
              title={img?.name}
              width={200}
            />
          ))}
        </Space>
      );
    };
  } else if (fieldType === "File") {
    props.render = (value: any) => {
      return (
        <Space wrap>
          {JSON.parse((value as any) || "[]")?.map?.((file: any) => (
            <FileField
              key={file?.response?.name}
              src={file?.thumbUrl}
              title={file?.name}
            />
          ))}
        </Space>
      );
    };
  }
  if (tableConfig.header.sorter.includes(fieldName)) {
    props.defaultSortOrder = getDefaultSortOrder(fieldName, sorter);
    props.sorter = true;
  }
  if (tableConfig.header.filter.includes(fieldName)) {
    const field = (model as any)[fieldName];
    const { type: fieldType, args } = col.uiType.formItem;

    if (
      field.kind === "enum" ||
      ["Radio", "Select", "CheckBox"].includes(fieldType)
    ) {
      let options = {};
      if (field.kind === "enum") {
        options = (modelsEnum as any)[field.type];
      } else {
        options = (args as any).options.reduce(
          (acc: Record<string, string>, cur: string) => {
            acc[cur] = cur;
            return acc;
          },
          {}
        );
      }
      props.filterDropdown = (p: FilterDropdownProps) => {
        const { setSelectedKeys, confirm } = p;
        return (
          <FilterDropdown
            {...p}
            clearFilters={() => {
              setSelectedKeys([]);
              confirm?.();
            }}
          >
            <Select
              style={{ minWidth: 200 }}
              mode="multiple"
              placeholder={t(
                `resources.${resourceName}.filters.${fieldName}`,
                "Select value"
              )}
              options={Object.entries(options).map(([k, v]) => ({
                value: v,
                label: t(
                  `resources.${resourceName}.enums.${fieldName}.${k}`,
                  k
                ),
              }))}
              /* defaultValue="PUBLISHED" */
            />
          </FilterDropdown>
        );
      };
      props.defaultFilteredValue = getDefaultFilter(fieldName, filters);
    } else if (field.kind === "object") {
      props.filterDropdown = (p: FilterDropdownProps) => {
        const { setSelectedKeys, confirm } = p;
        return (
          <FilterDropdown
            {...p}
            clearFilters={() => {
              setSelectedKeys([]);
              confirm?.();
            }}
            mapValue={(selectedKeys) =>
              selectedKeys.map((i) => parseInt(i.toString()))
            }
          >
            <Select
              style={{ minWidth: 200 }}
              mode="multiple"
              placeholder={t(
                `resources.${field.type.toLowerCase()}.name`,
                field.type
              )}
              {...relationSelectProps[field.name]}
            />
          </FilterDropdown>
        );
      };
      props.defaultFilteredValue = getDefaultFilter(
        `${field.name}.id`,
        filters,
        "in"
      );
    }
  }
  return <Table.Column {...props} {...col} />;
}
