import { ArOverlayFindAndPickConfiguration } from '../barcode/ArTrackingOverlayConfiguration';
import { ArOverlayGeneralConfiguration } from '../barcode/ArTrackingOverlayConfiguration';
import { ArOverlayPolygonConfiguration } from '../barcode/ArTrackingOverlayConfiguration';
import { BackgroundStyle } from '../common/Common';
import { BadgeStyle } from '../common/Common';
import { BadgedButton } from '../common/Common';
import { BarcodeInfoMapping } from '../barcode/BarcodeInfoMapping';
import { BarcodeItemConfiguration } from '../barcode/ArTrackingOverlayConfiguration';
import { BarcodeItemErrorState } from '../barcode/BarcodeInfoMapping';
import { BarcodeItemInfoPosition } from '../barcode/ArTrackingOverlayConfiguration';
import { BarcodeItemMapper } from '../BarcodeItemMapper';
import { BarcodeUseCase } from '../barcode/BarcodeUseCase';
import { ButtonConfiguration } from '../common/Common';
import { CollapsedVisibleHeight } from '../barcode/MultipleScanningModeUseCase';
import { DeepPartial, PartiallyConstructible } from '../../utils';
import { FindAndPickArOverlayPolygonConfiguration } from '../barcode/ArTrackingOverlayConfiguration';
import { FindAndPickBadgeConfiguration } from '../barcode/ArTrackingOverlayConfiguration';
import { ForegroundStyle } from '../common/Common';
import { IconStyle } from '../common/Common';
import { ManualCountEditDialog } from '../barcode/MultipleScanningModeUseCase';
import { MultipleBarcodesScanningMode } from '../barcode/MultipleScanningModeUseCase';
import { MultipleScanningMode } from '../barcode/MultipleScanningModeUseCase';
import { PolygonStyle } from '../common/Common';
import { ScanbotAlertDialog } from '../common/ScanbotAlertDialog';
import { SheetContent } from '../barcode/MultipleScanningModeUseCase';
import { SheetMode } from '../barcode/MultipleScanningModeUseCase';
import { Sheet } from '../barcode/MultipleScanningModeUseCase';
import { SingleScanningMode } from '../barcode/SingleScanningModeUseCase';
import { StyledText } from '../common/Common';
import { SwipeToDelete } from '../barcode/MultipleScanningModeUseCase';

/**
Configuration of the barcode to find and scan.
*/
export class ExpectedBarcode extends PartiallyConstructible {
  /**
    Value of the barcode to find. If not set, any barcode value will be accepted.
    */
  public barcodeValue: string;
  /**
    Title of the barcode to find.
    */
  public title: string | null;
  /**
    Image of the barcode to find.
    */
  public image: string | null;
  /**
    Number of barcodes with given symbology/value required to scan.
    Default is 1
    */
  public count: number = 1;
  /**
   Use this key to display the original barcode image
   */
  public static readonly barcodeImageKey = 'BARCODE_IMAGE';

  /** @param source {@displayType `DeepPartial<ExpectedBarcode>`} */
  public constructor(source: DeepPartial<ExpectedBarcode> = {}) {
    super();
    if (source.barcodeValue !== undefined) {
      this.barcodeValue = source.barcodeValue;
    } else {
      throw new Error('barcodeValue must be present in constructor argument');
    }
    if (source.title !== undefined) {
      this.title = source.title != null ? source.title : null;
    } else {
      throw new Error('title must be present in constructor argument');
    }
    if (source.image !== undefined) {
      this.image = source.image != null ? source.image : null;
    } else {
      throw new Error('image must be present in constructor argument');
    }
    if (source.count !== undefined) {
      this.count = source.count;
    }
  }
}

/**
Configuration of the Find and Pick barcode scanning mode.
*/
export class FindAndPickScanningMode extends PartiallyConstructible {
  public readonly _type: 'FindAndPickScanningMode' = 'FindAndPickScanningMode';
  /**
    Color of the selected barcode.
    Default is "?sbColorPositive"
    */
  public scanningCompletedColor: string = '?sbColorPositive';
  /**
    Color of the partially scanned barcode.
    Default is "?sbColorWarning"
    */
  public scanningPartiallyColor: string = '?sbColorWarning';
  /**
    Color of the not scanned barcode .
    Default is "?sbColorOutline"
    */
  public scanningNotScannedColor: string = '?sbColorOutline';
  /**
    If the user is allowed to finish the scanning process without scanning all the expected barcodes.
    Default is false
    */
  public allowPartialScan: boolean = false;
  /**
    List of barcodes that the user has to find and scan.
    */
  public expectedBarcodes: ExpectedBarcode[] = [];
  /**
    Time interval in milliseconds before a barcode is counted again. 0 = no delay. The default value is 1000.
    Default is 1000
    */
  public countingRepeatDelay: number = 1000;
  /**
    Configuration of the preview mode for the barcodes required to be found and scanned.
    */
  public sheet: Sheet = new Sheet({
    mode: 'COLLAPSED_SHEET',
    collapsedVisibleHeight: 'SMALL',
    listButton: new BadgedButton({
      badgeBackgroundColor: '?sbColorSurface',
      badgeForegroundColor: '?sbColorPrimary',
      visible: true,
      backgroundColor: '?sbColorSurfaceHigh',
      foregroundColor: '?sbColorOnPrimary',
      activeBackgroundColor: '?sbColorSurfaceHigh',
      activeForegroundColor: '?sbColorOnPrimary',
    }),
  });
  /**
    Configuration of the list of barcodes required to be found and scanned.
    */
  public sheetContent: SheetContent = new SheetContent({
    sheetColor: '?sbColorSurface',
    dividerColor: '?sbColorOutline',
    manualCountChangeEnabled: true,
    manualCountOutlineColor: '?sbColorOutline',
    manualCountChangeColor: '?sbColorPrimary',
    title: new StyledText({
      visible: true,
      text: '?findAndPickSheetTitle',
      color: '?sbColorOnSurface',
      useShadow: false,
    }),
    clearAllButton: new ButtonConfiguration({
      visible: true,
      text: '?sheetResetButton',
      background: new BackgroundStyle({
        strokeColor: '#00000000',
        fillColor: '#00000000',
        strokeWidth: 1.0,
      }),
      foreground: new ForegroundStyle({
        iconVisible: false,
        color: '?sbColorOnSurface',
        useShadow: false,
      }),
    }),
    barcodeItemTitle: new StyledText({ text: 'BARCODE_TITLE', color: '?sbColorOnSurface' }),
    barcodeItemSubtitle: new StyledText({
      text: '?findAndPickSheetBarcodeItemSubtitle',
      color: '?sbColorOnSurfaceVariant',
    }),
    barcodeItemImageVisible: true,
    submitButton: new ButtonConfiguration({
      visible: true,
      text: '?sheetSubmitButton',
      background: new BackgroundStyle({
        strokeColor: '#00000000',
        fillColor: '#00000000',
        strokeWidth: 1.0,
      }),
      foreground: new ForegroundStyle({
        iconVisible: false,
        color: '?sbColorOnSurface',
        useShadow: false,
      }),
    }),
    startScanningButton: new ButtonConfiguration({
      visible: true,
      text: '?sheetStartScanningButton',
      background: new BackgroundStyle({
        strokeColor: '?sbColorPrimary',
        fillColor: '?sbColorPrimary',
        strokeWidth: 1.0,
      }),
      foreground: new ForegroundStyle({
        iconVisible: false,
        color: '?sbColorOnPrimary',
        useShadow: false,
      }),
    }),
    placeholderTitle: new StyledText({
      text: '?sheetPlaceholderTitle',
      color: '?sbColorOnSurface',
    }),
    placeholderSubtitle: new StyledText({
      text: '?sheetPlaceholderSubtitle',
      color: '?sbColorOnSurfaceVariant',
    }),
    placeholderIconBackground: '?sbColorOutline',
    placeholderIcon: new IconStyle({ visible: true, color: '?sbColorOnSurface' }),
    swipeToDelete: new SwipeToDelete({
      enabled: false,
      backgroundColor: '?sbColorNegative',
      iconColor: '?sbColorOnPrimary',
    }),
  });
  /**
    Configuration of the dialog to manually edit the barcode count.
    */
  public manualCountEditDialog: ManualCountEditDialog = new ManualCountEditDialog({
    sheetColor: '?sbColorSurface',
    dividerColor: '?sbColorOutline',
    modalOverlayColor: '?sbColorModalOverlay',
    title: new StyledText({ text: '?manualCountEditDialogTitle', color: '?sbColorOnSurface' }),
    info: new StyledText({ text: '?manualCountEditDialogInfo', color: '?sbColorOnSurfaceVariant' }),
    updateButton: new ButtonConfiguration({
      visible: true,
      text: '?manualCountEditDialogUpdateButton',
      background: new BackgroundStyle({
        strokeColor: '?sbColorPrimary',
        fillColor: '?sbColorPrimary',
        strokeWidth: 1.0,
      }),
      foreground: new ForegroundStyle({
        iconVisible: false,
        color: '?sbColorOnPrimary',
        useShadow: false,
      }),
    }),
    cancelButton: new ButtonConfiguration({
      visible: true,
      text: '?manualCountEditDialogCancelButton',
      background: new BackgroundStyle({
        strokeColor: '#00000000',
        fillColor: '#00000000',
        strokeWidth: 1.0,
      }),
      foreground: new ForegroundStyle({
        iconVisible: false,
        color: '?sbColorPrimary',
        useShadow: false,
      }),
    }),
    clearTextButton: new IconStyle({ visible: true, color: '?sbColorOnSurfaceVariant' }),
  });
  /**
    Configuration of the AR overlay.
    */
  public arOverlay: ArOverlayFindAndPickConfiguration = new ArOverlayFindAndPickConfiguration({
    visible: true,
    automaticSelectionEnabled: true,
    polygon: new FindAndPickArOverlayPolygonConfiguration({
      partiallyScanned: new PolygonStyle({
        strokeColor: '?sbColorWarning',
        fillColor: '#00000000',
        strokeWidth: 3.0,
        cornerRadius: 5.0,
      }),
      rejected: new PolygonStyle({
        strokeColor: '?sbColorSurface',
        fillColor: '#00000000',
        strokeWidth: 3.0,
        cornerRadius: 5.0,
      }),
      completed: new PolygonStyle({
        strokeColor: '?sbColorPositive',
        fillColor: '#00000000',
        strokeWidth: 3.0,
        cornerRadius: 5.0,
      }),
    }),
    badge: new FindAndPickBadgeConfiguration({
      partiallyScanned: new BadgeStyle({
        visible: true,
        background: new BackgroundStyle({
          strokeColor: '#000000FF',
          fillColor: '?sbColorWarning',
          strokeWidth: 0.0,
        }),
        foregroundColor: '?sbColorOnSurface',
      }),
      rejected: new BadgeStyle({
        visible: true,
        background: new BackgroundStyle({
          strokeColor: '#000000FF',
          fillColor: '?sbColorSurface',
          strokeWidth: 0.0,
        }),
        foregroundColor: '?sbColorOnSurface',
      }),
      completed: new BadgeStyle({
        visible: true,
        background: new BackgroundStyle({
          strokeColor: '#000000FF',
          fillColor: '?sbColorPositive',
          strokeWidth: 0.0,
        }),
        foregroundColor: '?sbColorOnSurface',
      }),
    }),
  });
  /**
    If the partial scanned alert dialog is enabled.
    Default is true
    */
  public partialScannedAlertDialogEnabled: boolean = true;
  /**
    Configuration of the partial scanned alert dialog.
    */
  public partialScannedAlertDialog: ScanbotAlertDialog = new ScanbotAlertDialog({
    title: new StyledText({ text: '?findAndPickPartialAlertTitle', color: '?sbColorOnSurface' }),
    subtitle: new StyledText({
      text: '?findAndPickPartialAlertSubtitle',
      color: '?sbColorOnSurfaceVariant',
    }),
    sheetColor: '?sbColorSurface',
    modalOverlayColor: '?sbColorModalOverlay',
    dividerColor: '?sbColorOutline',
    okButton: new ButtonConfiguration({
      visible: true,
      text: '?findAndPickPartialAlertSubmitButton',
      background: new BackgroundStyle({
        strokeColor: '?sbColorPrimary',
        fillColor: '?sbColorPrimary',
        strokeWidth: 1.0,
      }),
      foreground: new ForegroundStyle({
        iconVisible: true,
        color: '?sbColorOnPrimary',
        useShadow: false,
      }),
    }),
    cancelButton: new ButtonConfiguration({
      visible: true,
      text: '?findAndPickPartialAlertCancelButton',
      background: new BackgroundStyle({
        strokeColor: '#00000000',
        fillColor: '#00000000',
        strokeWidth: 1.0,
      }),
      foreground: new ForegroundStyle({
        iconVisible: false,
        color: '?sbColorPrimary',
        useShadow: false,
      }),
    }),
  });
  /**
    If the confirmation alert dialog is enabled.
    Default is false
    */
  public confirmationAlertDialogEnabled: boolean = false;
  /**
    Configuration of the confirmation alert dialog.
    */
  public confirmationAlertDialog: ScanbotAlertDialog = new ScanbotAlertDialog({
    title: new StyledText({ text: '?findAndPickCompleteAlertTitle', color: '?sbColorOnSurface' }),
    subtitle: new StyledText({
      text: '?findAndPickCompleteAlertSubtitle',
      color: '?sbColorOnSurfaceVariant',
    }),
    sheetColor: '?sbColorSurface',
    modalOverlayColor: '?sbColorModalOverlay',
    dividerColor: '?sbColorOutline',
    okButton: new ButtonConfiguration({
      visible: true,
      text: '?findAndPickCompleteAlertSubmitButton',
      background: new BackgroundStyle({
        strokeColor: '?sbColorPrimary',
        fillColor: '?sbColorPrimary',
        strokeWidth: 1.0,
      }),
      foreground: new ForegroundStyle({
        iconVisible: true,
        color: '?sbColorOnPrimary',
        useShadow: false,
      }),
    }),
    cancelButton: new ButtonConfiguration({
      visible: true,
      text: '?findAndPickCompleteAlertCancelButton',
      background: new BackgroundStyle({
        strokeColor: '#00000000',
        fillColor: '#00000000',
        strokeWidth: 1.0,
      }),
      foreground: new ForegroundStyle({
        iconVisible: false,
        color: '?sbColorPrimary',
        useShadow: false,
      }),
    }),
  });

  /** @param source {@displayType `DeepPartial<FindAndPickScanningMode>`} */
  public constructor(source: DeepPartial<FindAndPickScanningMode> = {}) {
    super();
    if (source.scanningCompletedColor !== undefined) {
      this.scanningCompletedColor = source.scanningCompletedColor;
    }
    if (source.scanningPartiallyColor !== undefined) {
      this.scanningPartiallyColor = source.scanningPartiallyColor;
    }
    if (source.scanningNotScannedColor !== undefined) {
      this.scanningNotScannedColor = source.scanningNotScannedColor;
    }
    if (source.allowPartialScan !== undefined) {
      this.allowPartialScan = source.allowPartialScan;
    }
    if (source.expectedBarcodes !== undefined) {
      this.expectedBarcodes = source.expectedBarcodes.map((it) => new ExpectedBarcode(it));
    }
    if (source.countingRepeatDelay !== undefined) {
      this.countingRepeatDelay = source.countingRepeatDelay;
    }
    if (source.sheet !== undefined) {
      this.sheet = new Sheet(source.sheet);
    }
    if (source.sheetContent !== undefined) {
      this.sheetContent = new SheetContent(source.sheetContent);
    }
    if (source.manualCountEditDialog !== undefined) {
      this.manualCountEditDialog = new ManualCountEditDialog(source.manualCountEditDialog);
    }
    if (source.arOverlay !== undefined) {
      this.arOverlay = new ArOverlayFindAndPickConfiguration(source.arOverlay);
    }
    if (source.partialScannedAlertDialogEnabled !== undefined) {
      this.partialScannedAlertDialogEnabled = source.partialScannedAlertDialogEnabled;
    }
    if (source.partialScannedAlertDialog !== undefined) {
      this.partialScannedAlertDialog = new ScanbotAlertDialog(source.partialScannedAlertDialog);
    }
    if (source.confirmationAlertDialogEnabled !== undefined) {
      this.confirmationAlertDialogEnabled = source.confirmationAlertDialogEnabled;
    }
    if (source.confirmationAlertDialog !== undefined) {
      this.confirmationAlertDialog = new ScanbotAlertDialog(source.confirmationAlertDialog);
    }
  }
}
