import { proxy, useListener, useProps } from "@odoo/owl";
import { isColorValid } from "../../../helpers/color";
import { TABLE_STYLES_TEMPLATES, buildTableStyle } from "../../../helpers/table_presets";
import { UuidGenerator } from "../../../helpers/uuid";
import { Component } from "../../../owl3_compatibility_layer";
import { Color } from "../../../types/misc";
import { SpreadsheetChildEnv } from "../../../types/spreadsheet_env";
import { TableConfig, TableStyle, TableStyleTemplateName } from "../../../types/table";
import { cssPropertiesToCss } from "../../helpers/css";
import { types } from "../../props_validation";
import { TableStylePreview } from "../../tables/table_style_preview/table_style_preview";
import { TextInput } from "../../text_input/text_input";
import { RoundColorPicker } from "../components/round_color_picker/round_color_picker";
import { Section } from "../components/section/section";

const DEFAULT_TABLE_STYLE_COLOR = "#3C78D8";

interface State {
  pickerOpened: boolean;
  primaryColor: Color;
  selectedTemplateName: TableStyleTemplateName;
  styleName: string;
}

export class TableStyleEditorPanel extends Component<SpreadsheetChildEnv> {
  static template = "o-spreadsheet-TableStyleEditorPanel";
  static components = { Section, RoundColorPicker, TableStylePreview, TextInput };
  protected props = useProps({
    onCloseSidePanel: types.function(),
    onStylePicked: types.function<(styleId: string) => void>().optional(),
    styleId: types.string().optional(),
  });

  state = proxy<State>(this.getInitialState());

  setup() {
    useListener(window as any, "click", () => (this.state.pickerOpened = false));
  }

  getInitialState(): State {
    const editedStyle = this.props.styleId
      ? this.env.model.getters.getTableStyle(this.props.styleId)
      : null;
    return {
      pickerOpened: false,
      primaryColor: editedStyle?.primaryColor || DEFAULT_TABLE_STYLE_COLOR,
      selectedTemplateName: editedStyle?.templateName || "lightColoredText",
      styleName: editedStyle?.displayName || this.env.model.getters.getNewCustomTableStyleName(),
    };
  }

  togglePicker() {
    this.state.pickerOpened = !this.state.pickerOpened;
  }

  onColorPicked(color: Color) {
    this.state.primaryColor = isColorValid(color) ? color : DEFAULT_TABLE_STYLE_COLOR;
    this.state.pickerOpened = false;
  }

  onTemplatePicked(templateName: TableStyleTemplateName) {
    this.state.selectedTemplateName = templateName;
  }

  onConfirm() {
    const tableStyleId = this.props.styleId || UuidGenerator.smallUuid();
    this.env.model.dispatch("CREATE_TABLE_STYLE", {
      tableStyleId,
      tableStyleName: this.state.styleName,
      templateName: this.state.selectedTemplateName,
      primaryColor: this.state.primaryColor,
    });
    this.props.onStylePicked?.(tableStyleId);
    this.props.onCloseSidePanel();
  }

  onCancel() {
    this.props.onCloseSidePanel();
  }

  onDelete() {
    if (!this.props.styleId) {
      return;
    }
    this.env.model.dispatch("REMOVE_TABLE_STYLE", { tableStyleId: this.props.styleId });
    this.props.onCloseSidePanel();
  }

  get colorPreviewStyle() {
    return cssPropertiesToCss({ background: this.state.primaryColor });
  }

  get tableTemplates() {
    return Object.keys(TABLE_STYLES_TEMPLATES).filter((templateName) => templateName !== "none");
  }

  get previewTableConfig(): TableConfig {
    return {
      bandedColumns: false,
      bandedRows: true,
      firstColumn: false,
      lastColumn: false,
      numberOfHeaders: 1,
      totalRow: true,
      hasFilters: true,
      styleId: "",
    };
  }

  get selectedStyle() {
    return this.computeTableStyle(this.state.selectedTemplateName);
  }

  computeTableStyle(templateName: TableStyleTemplateName): TableStyle {
    return buildTableStyle(this.state.styleName, templateName, this.state.primaryColor);
  }
}
