import type { ControlType, DropdownOption, FieldColor } from '../domain/types';

export interface InsertTypedControlSpec {
  alias: string;
  color?: FieldColor;
  controlType: ControlType;
  dateFormat?: string;
  debug?: boolean;
  defaultChecked: boolean;
  defaultValue: string;
  options: DropdownOption[];
  lock?: 'contentLocked' | 'sdtContentLocked' | 'unlocked';
  placeholder: string;
  selectedIndex: number;
  tag: string;
}

export interface WriteTextDefaultSpec {
  tag: string;
  value: string;
}

export interface ReadControlTextSpec {
  tag: string;
}

export interface UpdateControlSpec {
  alias: string;
  controlConfig: null | Record<string, unknown>;
  controlType: string;
  currentTag: string;
  lock: 'contentLocked' | 'sdtContentLocked' | 'unlocked';
  tag: string;
}

export interface FormulaResultLockSnapshot {
  locks: Array<{ lock: string; tag: string }>;
  primaryTag: string;
}

export interface FormulaResultLockSpec {
  mode: 'lock' | 'restore' | 'verify';
  primaryTag?: string;
  snapshot?: FormulaResultLockSnapshot;
}

export interface OnlyOfficeRange {
  GetText?: () => string;
  GetTextPr?: () => unknown;
  SetTextPr?: (value: unknown) => unknown;
}

export interface OnlyOfficeContentControl {
  AddText?: (value: string) => unknown;
  AddElement?: (value: unknown, index: number) => unknown;
  Delete?: (keepContent: boolean) => unknown;
  GetAlias?: () => string;
  GetDropdownList?: () => {
    Add?: (display: string, value: string) => unknown;
    Clear?: () => unknown;
    GetAllItems?: () => Array<{ GetText?: () => string; GetValue?: () => string }>;
  };
  GetInternalId?: () => string;
  GetLock?: () => string;
  GetPlaceholderText?: () => string;
  GetRange?: () => OnlyOfficeRange;
  GetTag: () => string;
  IsBlockLevel?: () => boolean;
  IsCheckBox?: () => boolean;
  IsComboBox?: () => boolean;
  IsDatePicker?: () => boolean;
  IsDropDownList?: () => boolean;
  IsCheckBoxChecked?: () => boolean;
  RemoveAllElements?: () => unknown;
  SetAlias?: (value: string) => unknown;
  SetAppearance?: (value: string) => unknown;
  SetColor?: (value: unknown) => unknown;
  SetDate?: (value: Date) => unknown;
  SetDateFormat?: (value: string) => unknown;
  SetCheckBoxChecked?: (value: boolean) => unknown;
  SetLock?: (value: string) => unknown;
  SetPlaceholderText?: (value: string) => unknown;
  SetTag?: (value: string) => unknown;
  Select?: () => unknown;
  SelectListItem?: (value: string) => unknown;
  ToJSON?: (includeContent?: boolean) => string;
}

export interface OnlyOfficeParagraph {
  AddInlineLvlSdt: (control: OnlyOfficeContentControl) => unknown;
  AddText: (value: string) => unknown;
}

export interface OnlyOfficeRun {
  AddText?: (value: string) => unknown;
  GetTextPr?: () => unknown;
}

export interface OnlyOfficeDocument {
  AcceptAllRevisionChanges?: () => unknown;
  Document?: {
    HaveRevisionChanges?: (includeCurrentUser: boolean) => unknown;
    SetTrackRevisions?: (enabled: boolean) => unknown;
  };
  GetAllContentControls: () => OnlyOfficeContentControl[];
  GetCurrentRun?: () => OnlyOfficeRun | null;
  GetRangeBySelect?: () => OnlyOfficeRange | null;
  InsertContent?: (items: unknown[], replaceSelection: boolean) => unknown;
  IsTrackRevisions?: () => unknown;
  SetTrackRevisions?: (enabled: boolean) => unknown;
}

export interface OnlyOfficeApi {
  CreateBlockLvlSdt?: () => OnlyOfficeContentControl;
  CreateCheckBoxContentControl?: (properties: { checked: boolean; checkedSymbol: number; uncheckedSymbol: number }) => OnlyOfficeContentControl;
  CreateComboBoxContentControl?: (options: DropdownOption[], selectedIndex: number) => OnlyOfficeContentControl;
  CreateDatePickerContentControl?: (properties: { format: string; lang: string }) => OnlyOfficeContentControl;
  CreateInlineLvlSdt?: () => OnlyOfficeContentControl;
  CreateParagraph: () => OnlyOfficeParagraph;
  CreateRGBColor?: (r: number, g: number, b: number) => unknown;
  CreateRun: () => OnlyOfficeRun;
  GetDocument: () => OnlyOfficeDocument;
}

export interface OnlyOfficeScope {
  [key: string]: unknown;
  elnTemplateInsert?: InsertTypedControlSpec;
  elnTemplateFormulaLocks?: FormulaResultLockSpec;
  elnTemplateList?: Record<string, never>;
  elnTemplateReadText?: ReadControlTextSpec;
  elnTemplateReview?: Record<string, never>;
  elnTemplateTextDefault?: WriteTextDefaultSpec;
  elnTemplateUpdateControls?: { removals?: string[]; updates: UpdateControlSpec[] };
}

export interface OfficeContentControl {
  Alias?: string;
  ControlConfig?: Record<string, unknown>;
  ControlRole?: string;
  ControlType?: ControlType;
  InternalId?: string;
  BindingId?: string;
  Lock?: string;
  Tag?: string;
  Text?: string;
}

export type OnlyOfficeCommand = () => string;

export interface AscPlugin {
  button?: (id: number) => void;
  callCommand: (command: OnlyOfficeCommand, isClose: boolean, isCalc: boolean, callback: (result: unknown) => void) => boolean | void;
  executeCommand: (command: string, data: string) => unknown;
  executeMethod: (name: string, args: unknown[], callback: (result: unknown) => void) => boolean | void;
  info?: { options?: unknown };
  init?: () => void;
  onThemeChanged?: (theme: unknown) => void;
  onThemeChangedBase: (theme: unknown) => void;
}

export interface AscGlobal {
  plugin: AscPlugin;
  scope: OnlyOfficeScope;
}

declare global {
  const Api: OnlyOfficeApi;
  const Asc: { scope: OnlyOfficeScope };

  interface Window {
    Asc?: AscGlobal;
  }
}
