/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import {
  Button,
  ButtonGroup,
  Intent,
  Menu,
  MenuItem,
  Popover,
  Position,
  ResizeSensor,
} from '@blueprintjs/core';
import { IconNames } from '@blueprintjs/icons';
import type { Timezone } from 'chronoshift';
import classNames from 'classnames';
import type { Column, QueryResult, SqlExpression, SqlQuery } from 'druid-query-toolkit';
import { SqlLiteral } from 'druid-query-toolkit';
import React, { useState } from 'react';

import { useMemoWithPrevious } from '../../../../hooks';
import {
  isEmpty,
  localStorageGetJson,
  LocalStorageKeys,
  localStorageSetJson,
  mapRecord,
  Stage,
} from '../../../../utils';
import type {
  Measure,
  ModuleState,
  ParameterDefinition,
  ParameterValues,
  QuerySource,
} from '../../models';
import { effectiveParameterDefault, removeUndefinedParameterValues } from '../../models';
import { ModuleRepository } from '../../module-repository/module-repository';
import { adjustTransferValue, normalizeType } from '../../utils';
import { ControlPane } from '../control-pane/control-pane';
import { DroppableContainer } from '../droppable-container/droppable-container';
import { ErrorBoundary } from '../error-boundary/error-boundary';
import { FilterPane } from '../filter-pane/filter-pane';
import { Issue } from '../issue/issue';
import { ModulePicker } from '../module-picker/module-picker';

import './module-pane.scss';

function getStickyParameterValuesForModule(moduleId: string): ParameterValues {
  return localStorageGetJson(LocalStorageKeys.EXPLORE_STICKY)?.[moduleId] || {};
}

function fillInDefaults(
  parameterValues: ParameterValues,
  previousParameterValues: ParameterValues | undefined,
  parameters: Record<string, ParameterDefinition>,
  querySource: QuerySource,
  where: SqlExpression,
): Record<string, any> {
  const parameterValuesWithDefaults = { ...parameterValues };
  Object.entries(parameters).forEach(([propName, propDefinition]) => {
    if (typeof parameterValuesWithDefaults[propName] !== 'undefined') return;
    parameterValuesWithDefaults[propName] = effectiveParameterDefault(
      propDefinition,
      parameterValues,
      querySource,
      where,
      previousParameterValues?.[propName],
    );
  });
  return parameterValuesWithDefaults;
}

export interface ModulePaneProps {
  className: string;
  moduleState: ModuleState;
  setModuleState(moduleState: ModuleState): void;
  onDelete(): void;
  querySource: QuerySource;
  timezone: Timezone;
  where: SqlExpression;
  setWhere(where: SqlExpression): void;

  runSqlQuery(
    query: string | SqlQuery | { query: string | SqlQuery; timezone?: Timezone },
  ): Promise<QueryResult>;

  onAddToSourceQueryAsColumn?(expression: SqlExpression): void;
  onAddToSourceQueryAsMeasure?(measure: Measure): void;
}

export const ModulePane = function ModulePane(props: ModulePaneProps) {
  const {
    className,
    moduleState,
    setModuleState,
    onDelete,
    querySource,
    timezone,
    where,
    setWhere,
    runSqlQuery,
    onAddToSourceQueryAsColumn,
    onAddToSourceQueryAsMeasure,
  } = props;
  const { moduleId, moduleWhere, parameterValues, showModuleWhere, showControls } = moduleState;
  const [stage, setStage] = useState<Stage | undefined>();

  const module = ModuleRepository.getModule(moduleId);

  function updateParameterValues(newParameterValues: ParameterValues) {
    if (!module) return;

    // Evaluate sticky-ness
    const currentExploreSticky = localStorageGetJson(LocalStorageKeys.EXPLORE_STICKY) || {};
    const currentModuleSticky = currentExploreSticky[moduleId] || {};
    const newModuleSticky = {
      ...currentModuleSticky,
      ...mapRecord(newParameterValues, (v, k) => (module.parameters[k]?.sticky ? v : undefined)),
    };

    localStorageSetJson(LocalStorageKeys.EXPLORE_STICKY, {
      ...currentExploreSticky,
      [moduleId]: isEmpty(newModuleSticky) ? undefined : newModuleSticky,
    });

    setModuleState(
      moduleState.changeParameterValues(
        removeUndefinedParameterValues(
          { ...parameterValues, ...newParameterValues },
          module.parameters,
          querySource,
          where,
        ),
      ),
    );
  }

  const parameterValuesWithDefaults: ParameterValues = useMemoWithPrevious(
    previousParameterValuesWithDefaults => {
      if (!module) return {};
      return fillInDefaults(
        parameterValues,
        previousParameterValuesWithDefaults,
        module.parameters,
        querySource,
        where,
      );
    },
    [parameterValues, module, querySource],
  );

  let content: React.ReactNode;
  if (module) {
    const modelIssue = undefined; // AutoForm.issueWithModel(moduleTileConfig.config, module.configFields);
    if (modelIssue) {
      content = <Issue issue={modelIssue} />;
    } else if (stage) {
      content = React.createElement(module.component, {
        stage,
        querySource,
        timezone,
        where,
        setWhere,
        moduleWhere,
        parameterValues: parameterValuesWithDefaults,
        setParameterValues: updateParameterValues,
        runSqlQuery,
      });
    }
  } else {
    content = <Issue issue={`Unknown module id: ${moduleId}`} />;
  }

  function onShowColumn(column: Column) {
    setModuleState(moduleState.applyShowColumn(column));
  }

  function onShowMeasure(measure: Measure) {
    setModuleState(moduleState.applyShowMeasure(measure));
  }

  const moduleHasFilter = !SqlLiteral.isTrue(moduleWhere);
  return (
    <div
      className={classNames(
        'module-pane',
        className,
        showControls ? 'show-controls' : 'no-controls',
        showModuleWhere ? 'show-filter' : 'no-filter',
      )}
    >
      {showModuleWhere && (
        <FilterPane
          querySource={querySource}
          extraFilter={where}
          timezone={timezone}
          filter={moduleWhere}
          onFilterChange={newFilter => setModuleState(moduleState.changeModuleWhere(newFilter))}
          runSqlQuery={runSqlQuery}
        />
      )}
      <div className="module-control-bar">
        <ModulePicker
          selectedModuleId={moduleId}
          onSelectedModuleIdChange={newModuleId => {
            let newParameterValues = getStickyParameterValuesForModule(newModuleId);

            const oldModule = ModuleRepository.getModule(moduleId);
            const newModule = ModuleRepository.getModule(newModuleId);
            if (oldModule && newModule) {
              const oldModuleParameters = oldModule.parameters || {};
              const newModuleParameters = newModule.parameters || {};
              for (const paramName in oldModuleParameters) {
                const parameterValue = parameterValues[paramName];
                if (typeof parameterValue === 'undefined') continue;

                const oldParameterDefinition = oldModuleParameters[paramName];
                const transferGroup = oldParameterDefinition.transferGroup;
                if (typeof transferGroup !== 'string') continue;

                const normalizedType = normalizeType(oldParameterDefinition.type);
                const target = Object.entries(newModuleParameters).find(
                  ([_, def]) =>
                    def.transferGroup === transferGroup &&
                    normalizeType(def.type) === normalizedType,
                );
                if (!target) continue;

                newParameterValues = {
                  ...newParameterValues,
                  [target[0]]: adjustTransferValue(
                    parameterValue,
                    oldParameterDefinition.type,
                    target[1].type,
                  ),
                };
              }
            }

            setModuleState(
              moduleState.change({ moduleId: newModuleId, parameterValues: newParameterValues }),
            );
          }}
        />
        {module && !showControls && (
          <ControlPane
            querySource={querySource}
            where={where}
            onUpdateParameterValues={updateParameterValues}
            parameters={module.parameters}
            parameterValues={parameterValuesWithDefaults}
            compact
            onAddToSourceQueryAsColumn={onAddToSourceQueryAsColumn}
            onAddToSourceQueryAsMeasure={onAddToSourceQueryAsMeasure}
          />
        )}
      </div>
      <ButtonGroup className="corner-buttons">
        <Popover
          position={Position.BOTTOM_RIGHT}
          content={
            <Menu>
              <MenuItem
                icon={IconNames.RESET}
                text="Reset visualization parameters"
                onClick={() => {
                  setModuleState(
                    moduleState.changeParameterValues(getStickyParameterValuesForModule(moduleId)),
                  );
                }}
              />
              <MenuItem
                icon={IconNames.TRASH}
                text="Delete module"
                intent={Intent.DANGER}
                onClick={onDelete}
              />
            </Menu>
          }
        >
          <Button icon={IconNames.MORE} data-tooltip="More module options" minimal />
        </Popover>
        <Button
          icon={moduleHasFilter ? IconNames.FILTER_KEEP : IconNames.FILTER}
          data-tooltip={`${showModuleWhere ? 'Hide' : 'Show'} module filter bar${
            moduleHasFilter ? `\nCurrent filter: ${moduleWhere}` : ''
          }`}
          minimal
          active={showModuleWhere}
          onClick={() => setModuleState(moduleState.change({ showModuleWhere: !showModuleWhere }))}
        />
        <Button
          icon={IconNames.PROPERTIES}
          data-tooltip={`${showControls ? 'Hide' : 'Show'} module controls`}
          minimal
          active={showControls}
          onClick={() => setModuleState(moduleState.change({ showControls: !showControls }))}
        />
      </ButtonGroup>
      {showControls && module && (
        <div className="control-pane-container">
          <ControlPane
            querySource={querySource}
            where={where}
            onUpdateParameterValues={updateParameterValues}
            parameters={module.parameters}
            parameterValues={parameterValuesWithDefaults}
            onAddToSourceQueryAsColumn={onAddToSourceQueryAsColumn}
            onAddToSourceQueryAsMeasure={onAddToSourceQueryAsMeasure}
          />
        </div>
      )}
      <ResizeSensor
        onResize={entries => {
          if (entries.length !== 1) return;
          const newStage = new Stage(entries[0].contentRect.width, entries[0].contentRect.height);
          if (newStage.equals(stage)) return;
          setStage(newStage);
        }}
      >
        <DroppableContainer
          className="module-inner-container"
          onDropColumn={onShowColumn}
          onDropMeasure={onShowMeasure}
        >
          <ErrorBoundary>{content}</ErrorBoundary>
        </DroppableContainer>
      </ResizeSensor>
    </div>
  );
};
