/*
 This file is part of GNU Taler
 (C) 2021-2024 Taler Systems S.A.

 GNU Taler is free software; you can redistribute it and/or modify it under the
 terms of the GNU General Public License as published by the Free Software
 Foundation; either version 3, or (at your option) any later version.

 GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 A PARTICULAR PURPOSE.  See the GNU General Public License for more details.

 You should have received a copy of the GNU General Public License along with
 GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
 */

import {
  AbsoluteTime,
  Codec,
  MerchantPersona,
  buildCodecForObject,
  codecForAbsoluteTime,
  codecForConstString,
  codecForEither,
  codecOptional,
} from "@gnu-taler/taler-util";
import { buildStorageKey, useLocalStorage } from "@gnu-taler/web-util/browser";

export enum UIElement {
  sidebar_orders,
  sidebar_inventory,
  sidebar_categories,
  sidebar_wireTransfers,
  sidebar_templates,
  sidebar_kycStatus,
  sidebar_bankAccounts,
  sidebar_otpDevices,
  sidebar_webhooks,
  sidebar_tokenFamilies,
  sidebar_subscriptions,
  sidebar_statistics,
  sidebar_discounts,
  sidebar_settings,
  sidebar_password,
  sidebar_accessTokens,
  action_createOrderManually,
  option_otpDevicesOnTemplate,
  option_advanceOrderCreation,
  option_advanceInstanceSettings,
  action_useRevenueApi,
  option_paymentTimeoutOnTemplate,
  option_ageRestriction,
  option_inventoryTaxes,
}

export interface Preferences {
  hideKycUntil: AbsoluteTime;
  hideMissingAccountUntil: AbsoluteTime;
  dateFormat: "ymd" | "dmy" | "mdy";
  persona?: MerchantPersona;
}

const defaultSettings: Preferences = {
  hideKycUntil: AbsoluteTime.never(),
  hideMissingAccountUntil: AbsoluteTime.never(),
  dateFormat: "ymd",
  persona: undefined,
};

export const codecForPreferences = (): Codec<Preferences> =>
  buildCodecForObject<Preferences>()
    .property("hideKycUntil", codecForAbsoluteTime)
    .property("hideMissingAccountUntil", codecForAbsoluteTime)
    .property(
      "dateFormat",
      codecForEither(
        codecForConstString("ymd"),
        codecForConstString("dmy"),
        codecForConstString("mdy"),
      ),
    )
    .property(
      "persona",
      codecOptional(
        codecForEither(
          codecForConstString("developer"),
          codecForConstString("expert"),
          codecForConstString("offline-vending-machine"),
          codecForConstString("point-of-sale"),
          codecForConstString("digital-publishing"),
          codecForConstString("e-commerce"),
        ),
      ),
    )
    .build("Preferences");

const PREFERENCES_KEY = buildStorageKey(
  "merchant-preferences",
  codecForPreferences(),
);

export function usePreference(): [
  Readonly<Preferences>,
  <T extends keyof Preferences>(key: T, value: Preferences[T]) => void,
  (s: Preferences) => void,
] {
  const { value, update } = useLocalStorage(PREFERENCES_KEY, defaultSettings);
  function updateField<T extends keyof Preferences>(k: T, v: Preferences[T]) {
    const newValue = { ...value, [k]: v };
    update(newValue);
  }

  return [value, updateField, update];
}

export function dateFormatForSettings(s: Preferences): string {
  switch (s.dateFormat) {
    case "ymd":
      return "yyyy/MM/dd";
    case "dmy":
      return "dd/MM/yyyy";
    case "mdy":
      return "MM/dd/yyyy";
  }
}

export function datetimeFormatForSettings(s: Preferences): string {
  return dateFormatForSettings(s) + " HH:mm:ss";
}
