import { type FieldType, type OneOf } from './kintone-rest-api-client';
import {
  leftCalcType,
  linkType,
  type SpecialType,
  mayLookupTextNumber,
  mayLookupText,
  type AvailableRight,
  type AvailableLeft,
  isLookup,
  forCalc,
  type CalcTypeR2L,
  isSpecialType,
} from './join';
import type { SelectType } from '@/types/my-kintone';

// LEFT - rule
const availableLeftMappingType = {
  SINGLE_LINE_TEXT: [mayLookupText],
  MULTI_LINE_TEXT: ['MULTI_LINE_TEXT'],
  RICH_TEXT: ['RICH_TEXT'],
  NUMBER: [mayLookupTextNumber],
  CALC: [leftCalcType],
  RADIO_BUTTON: ['RADIO_BUTTON'],
  CHECK_BOX: ['CHECK_BOX'],
  MULTI_SELECT: ['MULTI_SELECT'], // TODO 带选项字段报错
  DROP_DOWN: ['DROP_DOWN'],
  USER_SELECT: ['USER_SELECT'],
  ORGANIZATION_SELECT: ['ORGANIZATION_SELECT'],
  GROUP_SELECT: ['GROUP_SELECT'],
  DATE: ['DATE', 'DATETIME'],
  TIME: ['TIME'],
  DATETIME: ['DATETIME'],
  LINK: [linkType, mayLookupText],
  //LOOKUP
  RECORD_NUMBER: [mayLookupTextNumber],
  CREATOR: ['USER_SELECT'],
  CREATED_TIME: ['DATETIME'],
  MODIFIER: ['USER_SELECT'],
  UPDATED_TIME: ['DATETIME'],
} as Record<FieldType, AvailableRight[]>;

// RIGHT
export type LookupTypeR2L = SpecialType<'LOOKUP_FROM_RIGHT', Array<FieldType | CalcTypeR2L>>;

export const isSameLookupOr = (format: Array<FieldType | CalcTypeR2L>): LookupTypeR2L => {
  return {
    type: 'LOOKUP_FROM_RIGHT',
    format,
    check: function (checkField: OneOf, selectedRightField?: OneOf) {
      if (selectedRightField && isLookup(selectedRightField)) {
        return isLookup(checkField) ? checkField.type === selectedRightField.type : false;
      }
      return !!this.format?.find((e) => {
        if (isSpecialType(e)) {
          return e.check(checkField, selectedRightField);
        }
        return e === checkField.type;
      });
    },
  };
};

const availableRightMappingType = {
  SINGLE_LINE_TEXT: [
    isSameLookupOr(['SINGLE_LINE_TEXT', 'NUMBER', forCalc(['NUMBER', 'NUMBER_DIGIT']), 'LINK', 'RECORD_NUMBER']),
  ],
  MULTI_LINE_TEXT: ['MULTI_LINE_TEXT'],
  RICH_TEXT: ['RICH_TEXT'],
  NUMBER: [isSameLookupOr(['NUMBER', forCalc(['NUMBER', 'NUMBER_DIGIT']), 'RECORD_NUMBER'])],
  RADIO_BUTTON: ['RADIO_BUTTON'],
  CHECK_BOX: ['CHECK_BOX'],
  MULTI_SELECT: ['MULTI_SELECT'], // TODO 带选项字段报错
  DROP_DOWN: ['DROP_DOWN'],
  USER_SELECT: ['USER_SELECT', 'CREATOR', 'MODIFIER'],
  ORGANIZATION_SELECT: ['ORGANIZATION_SELECT'],
  GROUP_SELECT: ['GROUP_SELECT'],
  DATE: ['DATE', forCalc(['DATE'])],
  TIME: ['TIME', forCalc(['TIME'])],
  DATETIME: ['DATE', 'DATETIME', forCalc(['DATETIME']), 'CREATED_TIME', 'UPDATED_TIME'],
  LINK: [linkType],
} as Record<FieldType, Array<AvailableLeft | LookupTypeR2L>>;

// methods
// undefined means all
export function getRightAvailableMappingType(left?: OneOf | '') {
  if (left === undefined) {
    return Object.keys(availableRightMappingType) as FieldType[];
  }
  return left ? availableLeftMappingType[left.type] : [];
}

// undefined means all
export function getLeftAvailableMappingType(right?: OneOf | '') {
  if (right === undefined) {
    return Object.keys(availableLeftMappingType) as FieldType[];
  }
  return right ? availableRightMappingType[right.type] : [];
}

export function isSelectType(field: OneOf): field is SelectType {
  return 'options' in field;
}
