<template>
  <div class="wallet-settings">
    <q-btn
      icon-right="more_vert"
      :label="$t('buttons.settings')"
      size="md"
      flat
    >
      <q-menu anchor="bottom right" self="top right">
        <q-list separator class="menu-list">
          <q-item
            v-close-popup
            clickable
            :disabled="!is_ready"
            @click.native="getPrivateKeys()"
          >
            <q-item-label header>{{
              $t("menuItems.showPrivateKeys")
            }}</q-item-label>
          </q-item>
          <q-item
            v-close-popup
            clickable
            :disabled="!is_ready"
            @click.native="showModal('change_password')"
          >
            <q-item-label header>{{
              $t("menuItems.changePassword")
            }}</q-item-label>
          </q-item>
          <q-item
            v-close-popup
            clickable
            :disabled="!is_ready"
            @click.native="showModal('export_transfers')"
          >
            <q-item-label header>{{
              $t("menuItems.exportTransfers")
            }}</q-item-label>
          </q-item>
          <q-item
            v-close-popup
            clickable
            :disabled="!is_ready"
            @click.native="showModal('rescan')"
          >
            <q-item-label header>{{
              $t("menuItems.rescanWallet")
            }}</q-item-label>
          </q-item>
          <q-item
            v-close-popup
            clickable
            :disabled="!is_ready"
            @click.native="showModal('key_image')"
          >
            <q-item-label header>{{
              $t("menuItems.manageKeyImages")
            }}</q-item-label>
          </q-item>
          <q-item
            v-close-popup
            clickable
            :disabled="!is_ready"
            @click.native="deleteWallet()"
          >
            <q-item-label header>{{
              $t("menuItems.deleteWallet")
            }}</q-item-label>
          </q-item>
        </q-list>
      </q-menu>
    </q-btn>

    <!-- Modals -->
    <!-- PRIVATE KEY MODAL -->
    <q-dialog
      v-model="modals.private_keys.visible"
      minimized
      @hide="closePrivateKeys()"
    >
      <div class="modal private-key-modal">
        <div class="modal-header">{{ $t("titles.privateKeys") }}</div>
        <div class="q-ma-md">
          <template v-if="secret.mnemonic">
            <h6 class="q-mb-xs q-mt-lg">
              {{ $t("strings.seedWords") }}
            </h6>
            <div class="row">
              <div class="col">
                {{ secret.mnemonic }}
              </div>
              <div class="col-auto">
                <q-btn
                  class="copy-btn"
                  color="primary"
                  padding="xs"
                  size="sm"
                  icon="file_copy"
                  @click="copyPrivateKey('mnemonic', $event)"
                >
                  <q-tooltip
                    anchor="center left"
                    self="center right"
                    :offset="[5, 10]"
                  >
                    {{ $t("menuItems.copySeedWords") }}
                  </q-tooltip>
                </q-btn>
              </div>
            </div>
          </template>

          <template v-if="secret.view_key != secret.spend_key">
            <h6 class="q-mb-xs">{{ $t("strings.viewKey") }}</h6>
            <div class="row">
              <div class="col" style="word-break:break-all;">
                {{ secret.view_key }}
              </div>
              <div class="col-auto">
                <q-btn
                  class="copy-btn"
                  color="primary"
                  padding="xs"
                  size="sm"
                  icon="file_copy"
                  @click="copyPrivateKey('view_key', $event)"
                >
                  <q-tooltip
                    anchor="center left"
                    self="center right"
                    :offset="[5, 10]"
                  >
                    {{ $t("menuItems.copyViewKey") }}
                  </q-tooltip>
                </q-btn>
              </div>
            </div>
          </template>

          <template v-if="!/^0*$/.test(secret.spend_key)">
            <h6 class="q-mb-xs">{{ $t("strings.spendKey") }}</h6>
            <div class="row">
              <div class="col" style="word-break:break-all;">
                {{ secret.spend_key }}
              </div>
              <div class="col-auto">
                <q-btn
                  class="copy-btn"
                  color="primary"
                  padding="xs"
                  size="sm"
                  icon="file_copy"
                  @click="copyPrivateKey('spend_key', $event)"
                >
                  <q-tooltip
                    anchor="center left"
                    self="center right"
                    :offset="[5, 10]"
                  >
                    {{ $t("menuItems.copySpendKey") }}
                  </q-tooltip>
                </q-btn>
              </div>
            </div>
          </template>

          <div class="q-mt-lg">
            <q-btn
              color="primary"
              :label="$t('buttons.close')"
              @click="hideModal('private_keys')"
            />
          </div>
        </div>
      </div>
    </q-dialog>

    <!-- RESCAN MODAL -->
    <q-dialog v-model="modals.rescan.visible" minimized>
      <div class="modal rescan-modal">
        <div class="a-ma-lg modal-header">{{ $t("titles.rescanWallet") }}</div>
        <div class="q-ma-md">
          <p>{{ $t("strings.rescanModalDescription") }}</p>

          <div class="q-mt-lg">
            <q-radio
              v-model="modals.rescan.type"
              val="full"
              :label="$t('fieldLabels.rescanFullBlockchain')"
            />
          </div>
          <div class="q-mt-sm">
            <q-radio
              v-model="modals.rescan.type"
              val="spent"
              :label="$t('fieldLabels.rescanSpentOutputs')"
            />
          </div>

          <div class="q-mt-xl text-right">
            <q-btn
              flat
              class="q-mr-sm"
              :label="$t('buttons.close')"
              @click="hideModal('rescan')"
            />
            <q-btn
              color="primary"
              :label="$t('buttons.rescan')"
              @click="rescanWallet()"
            />
          </div>
        </div>
      </div>
    </q-dialog>

    <!-- KEY IMAGE MODAL -->
    <q-dialog
      v-model="modals.key_image.visible"
      class="key-image-modal"
      minimized
    >
      <div class="modal key-image-modal">
        <div class="modal-header">
          <!-- Export/Import key images -->
          {{
            $t("dialog.keyImages.title", {
              type: $t(
                `dialog.keyImages.${modals.key_image.type.toLowerCase()}`
              )
            })
          }}
        </div>
        <div class="q-ma-md">
          <div class="row q-mb-md">
            <div class="q-mr-xl">
              <q-radio
                v-model="modals.key_image.type"
                val="Export"
                :label="$t('dialog.keyImages.export')"
              />
            </div>
            <div>
              <q-radio
                v-model="modals.key_image.type"
                val="Import"
                :label="$t('dialog.keyImages.import')"
              />
            </div>
          </div>

          <template v-if="modals.key_image.type == 'Export'">
            <OxenField
              class="q-mt-lg"
              :label="$t('fieldLabels.keyImages.exportDirectory')"
              disable-hover
            >
              <q-input
                v-model="modals.key_image.export_path"
                disable
                borderless
              />
              <input
                id="keyImageExportPath"
                ref="keyImageExportSelect"
                class="image-path"
                type="file"
                webkitdirectory
                directory
                hidden
                @change="setKeyImageExportPath"
              />
              <q-btn color="primary" @click="selectKeyImageExportPath">{{
                $t("buttons.browse")
              }}</q-btn>
            </OxenField>
          </template>
          <template v-if="modals.key_image.type == 'Import'">
            <OxenField
              class="q-mt-lg"
              :label="$t('fieldLabels.keyImages.importFile')"
              disable-hover
            >
              <q-input
                v-model="modals.key_image.import_path"
                disable
                borderless
              />
              <input
                id="keyImageImportPath"
                ref="keyImageImportSelect"
                type="file"
                class="image-path"
                hidden
                @change="setKeyImageImportPath"
              />
              <q-btn color="primary" @click="selectKeyImageImportPath">{{
                $t("buttons.browse")
              }}</q-btn>
            </OxenField>
          </template>

          <div class="q-mt-lg text-right">
            <q-btn
              flat
              class="q-mr-sm"
              :label="$t('buttons.close')"
              @click="hideModal('key_image')"
            />
            <q-btn
              color="primary"
              :label="$t('buttons.' + modals.key_image.type.toLowerCase())"
              @click="doKeyImages()"
            />
          </div>
        </div>
      </div>
    </q-dialog>

    <!-- CHANGE PASSWORD MODAL -->
    <q-dialog
      v-model="modals.change_password.visible"
      minimized
      @hide="clearChangePassword()"
    >
      <div class="modal password-modal">
        <div class="modal-header">{{ $t("titles.changePassword") }}</div>
        <div class="q-ma-md">
          <q-input
            v-model="modals.change_password.old_password"
            type="password"
            :label="$t('fieldLabels.oldPassword')"
          />
          <q-input
            v-model="modals.change_password.new_password"
            type="password"
            :label="$t('fieldLabels.newPassword')"
          />

          <q-input
            v-model="modals.change_password.new_password_confirm"
            type="password"
            :label="$t('fieldLabels.confirmNewPassword')"
          />

          <div class="q-mt-xl text-right">
            <q-btn
              flat
              class="q-mr-sm"
              :label="$t('buttons.close')"
              @click="hideModal('change_password')"
            />
            <q-btn
              color="primary"
              :label="$t('buttons.change')"
              @click="doChangePassword()"
            />
          </div>
        </div>
      </div>
    </q-dialog>
    <!-- EXPORT TRANSFERS MODAL -->
    <q-dialog
      v-model="modals.export_transfers.visible"
      class="export-transfers-modal"
      minimized
    >
      <div class="modal export-transfers-modal">
        <div class="modal-header">
          <!-- Export Transfers as CSV -->
          {{ $t("dialog.exportTransfers.title") }}
        </div>
        <div class="q-ma-md">
          <template>
            <OxenField
              class="q-mt-lg"
              :label="$t('fieldLabels.exportTransfers.exportDirectory')"
              disable-hover
            >
              <q-input
                v-model="modals.export_transfers.export_path"
                disable
                borderless
              />
              <input
                id="exportTransfersExportPath"
                ref="exportTransfersExportSelect"
                class="export-transfers-path"
                type="file"
                webkitdirectory
                directory
                hidden
                @change="setExportTransfersExportPath"
              />
              <q-btn color="primary" @click="selectExportTransfersExportPath">{{
                $t("buttons.browse")
              }}</q-btn>
            </OxenField>
          </template>

          <div class="q-mt-lg text-right">
            <q-btn
              flat
              class="q-mr-sm"
              :label="$t('buttons.close')"
              @click="hideModal('export_transfers')"
            />
            <q-btn
              color="primary"
              :label="$t('buttons.export')"
              @click="doExportTransfers()"
            />
          </div>
        </div>
      </div>
    </q-dialog>
  </div>
</template>

<script>
const { clipboard } = require("electron");
import { mapState } from "vuex";
import WalletPassword from "src/mixins/wallet_password";
import OxenField from "components/oxen_field";

export default {
  name: "WalletSettings",
  components: {
    OxenField
  },
  mixins: [WalletPassword],
  data() {
    return {
      modals: {
        private_keys: {
          visible: false
        },
        rescan: {
          visible: false,
          type: "full"
        },
        key_image: {
          visible: false,
          type: "Export",
          export_path: "",
          import_path: ""
        },
        export_transfers: {
          visible: false,
          export_path: ""
        },
        change_password: {
          visible: false,
          old_password: "",
          new_password: "",
          new_password_confirm: ""
        }
      }
    };
  },
  computed: mapState({
    theme: state => state.gateway.app.config.appearance.theme,
    info: state => state.gateway.wallet.info,
    secret: state => state.gateway.wallet.secret,
    wallet_data_dir: state => state.gateway.app.config.app.wallet_data_dir,
    is_ready() {
      return this.$store.getters["gateway/isReady"];
    },
    locale() {
      return this.$q.lang.getLocale();
    }
  }),
  watch: {
    secret: {
      handler(val, old) {
        if (val.view_key == old.view_key) return;
        switch (this.secret.view_key) {
          case "":
            break;
          case -1:
            this.$q.notify({
              type: "negative",
              timeout: 1000,
              message: this.$t(this.secret.mnemonic)
            });
            this.$store.commit("gateway/set_wallet_data", {
              secret: {
                mnemonic: "",
                spend_key: "",
                view_key: ""
              }
            });
            break;
          default:
            this.showModal("private_keys");
            break;
        }
      },
      deep: true
    }
  },
  created() {
    const path = require("upath");
    this.modals.key_image.export_path = path.join(
      this.wallet_data_dir,
      "images",
      this.info.name
    );
    this.modals.key_image.import_path = path.join(
      this.wallet_data_dir,
      "images",
      this.info.name,
      "key_image_export"
    );
    this.modals.export_transfers.export_path = path.join(
      this.wallet_data_dir,
      "CSV",
      this.info.name
    );
  },
  methods: {
    showModal(which) {
      if (!this.is_ready) return;
      this.modals[which].visible = true;
    },
    hideModal(which) {
      this.modals[which].visible = false;
    },
    copyPrivateKey(type, event) {
      event.stopPropagation();
      for (let i = 0; i < event.path.length; i++) {
        if (event.path[i].tagName == "BUTTON") {
          event.path[i].blur();
          break;
        }
      }

      if (this.secret[type] == null) {
        this.$q.notify({
          type: "negative",
          timeout: 1000,
          message: this.$t("notification.errors.copyingPrivateKeys")
        });
        return;
      }

      clipboard.writeText(this.secret[type]);

      let type_key = "seedWords";
      if (type === "spend_key") {
        type_key = "spendKey";
      } else if (type === "view_key") {
        type_key = "viewKey";
      }
      const type_title = this.$t("dialog.copyPrivateKeys." + type_key);

      this.$q
        .dialog({
          title: this.$t("dialog.copyPrivateKeys.title", {
            type: type_title
          }),
          message: this.$t("dialog.copyPrivateKeys.message"),
          ok: {
            label: this.$t("dialog.buttons.ok"),
            color: "primary"
          }
        })
        .onDismiss(() => null)
        .onCancel(() => null)
        .onOk(() => {
          this.$q.notify({
            type: "positive",
            timeout: 1000,
            message: this.$t("notification.positive.copied", {
              item: this.$t("strings." + type_key)
            })
          });
        });
    },
    async getPrivateKeys() {
      if (!this.is_ready) return;
      let passwordDialog = await this.showPasswordConfirmation({
        title: this.$t("dialog.showPrivateKeys.title"),
        noPasswordMessage: this.$t("dialog.showPrivateKeys.message"),
        ok: {
          label: this.$t("dialog.showPrivateKeys.ok"),
          color: "primary"
        },
        cancel: {
          color: "tertiary",
          flat: true
        },
        color: "white"
      });
      passwordDialog
        .onOk(password => {
          // if no password set
          password = password || "";
          this.$gateway.send("wallet", "get_private_keys", {
            password
          });
        })
        .onDismiss(() => {})
        .onCancel(() => {});
    },
    closePrivateKeys() {
      this.hideModal("private_keys");
      setTimeout(() => {
        this.$store.commit("gateway/set_wallet_data", {
          secret: {
            mnemonic: "",
            spend_key: "",
            view_key: ""
          }
        });
      }, 500);
    },
    rescanWallet() {
      this.hideModal("rescan");
      if (this.modals.rescan.type == "full") {
        this.$q
          .dialog({
            title: this.$t("dialog.rescan.title"),
            message: this.$t("dialog.rescan.message"),
            ok: {
              label: this.$t("dialog.rescan.ok"),
              color: "primary"
            },
            cancel: {
              flat: true,
              label: this.$t("dialog.buttons.cancel")
            }
          })
          .onOk(() => {
            this.$gateway.send("wallet", "rescan_blockchain");
          })
          .onDismiss(() => {})
          .onCancel(() => {});
      } else {
        this.$gateway.send("wallet", "rescan_spent");
      }
    },
    selectKeyImageExportPath() {
      this.$refs.keyImageExportSelect.click();
    },
    setKeyImageExportPath(file) {
      this.modals.key_image.export_path = file.target.files[0].path;
    },
    selectKeyImageImportPath() {
      this.$refs.keyImageImportSelect.click();
    },
    setKeyImageImportPath(file) {
      this.modals.key_image.import_path = file.target.files[0].path;
    },
    selectExportTransfersExportPath() {
      this.$refs.exportTransfersExportSelect.click();
    },
    setExportTransfersExportPath(file) {
      this.modals.export_transfers.export_path = file.target.files[0].path;
    },
    async doKeyImages() {
      this.hideModal("key_image");

      const type = this.$t(
        `dialog.keyImages.${this.modals.key_image.type.toLowerCase()}`
      );

      let passwordDialog = await this.showPasswordConfirmation({
        title: this.$t("dialog.keyImages.title", { type }),
        noPasswordMessage: this.$t("dialog.keyImages.message", {
          type: type.toLocaleLowerCase(this.locale)
        }),
        ok: {
          label: type.toLocaleUpperCase(this.locale),
          color: "primary"
        },
        color: this.theme == "dark" ? "dark" : "white",
        cancel: {
          color: "tertiary",
          flat: true
        }
      });
      passwordDialog
        .onOk(password => {
          // if no password set
          password = password || "";
          if (this.modals.key_image.type == "Export")
            this.$gateway.send("wallet", "export_key_images", {
              password: password,
              path: this.modals.key_image.export_path
            });
          else if (this.modals.key_image.type == "Import")
            this.$gateway.send("wallet", "import_key_images", {
              password: password,
              path: this.modals.key_image.import_path
            });
        })
        .onCancel(() => {})
        .onDismiss(() => {});
    },
    doChangePassword() {
      let old_password = this.modals.change_password.old_password;
      let new_password = this.modals.change_password.new_password;
      let new_password_confirm = this.modals.change_password
        .new_password_confirm;

      if (new_password == old_password) {
        this.$q.notify({
          type: "negative",
          timeout: 1000,
          message: this.$t("notification.errors.newPasswordSame")
        });
      } else if (new_password != new_password_confirm) {
        this.$q.notify({
          type: "negative",
          timeout: 1000,
          message: this.$t("notification.errors.newPasswordNoMatch")
        });
      } else {
        this.hideModal("change_password");
        this.$gateway.send("wallet", "change_wallet_password", {
          old_password,
          new_password
        });
      }
    },
    clearChangePassword() {
      this.modals.change_password.old_password = "";
      this.modals.change_password.new_password = "";
      this.modals.change_password.new_password_confirm = "";
    },
    async doExportTransfers() {
      this.hideModal("export_transfers");

      let passwordDialog = await this.showPasswordConfirmation({
        title: this.$t("dialog.exportTransfers.title"),
        noPasswordMessage: this.$t("dialog.exportTransfers.message"),
        ok: {
          label: "export".toLocaleUpperCase(this.locale),
          color: "primary"
        },
        color: this.theme == "dark" ? "dark" : "white",
        cancel: {
          color: "tertiary",
          flat: true
        }
      });
      passwordDialog
        .onOk(password => {
          // if no password set
          password = password || "";
          this.$gateway.send("wallet", "export_transfers", {
            password: password,
            path: this.modals.export_transfers.export_path
          });
        })
        .onCancel(() => {})
        .onDismiss(() => {});
    },
    deleteWallet() {
      if (!this.is_ready) return;
      this.$q
        .dialog({
          title: this.$t("dialog.deleteWallet.title"),
          message: this.$t("dialog.deleteWallet.message"),
          ok: {
            label: this.$t("dialog.deleteWallet.ok"),
            color: "red"
          },
          cancel: {
            flat: true,
            label: this.$t("dialog.buttons.cancel"),
            color: this.theme == "dark" ? "white" : "dark"
          },
          color: "#1F1C47"
        })
        .onOk(async () => {
          const hasPassword = await this.hasPassword();
          if (hasPassword) {
            this.$q
              .dialog({
                title: this.$t("dialog.deleteWallet.title"),
                message: this.$t("dialog.password.message"),
                prompt: {
                  model: "",
                  type: "password"
                },
                ok: {
                  label: this.$t("dialog.deleteWallet.ok"),
                  color: "negative"
                },
                cancel: {
                  flat: true,
                  label: this.$t("dialog.buttons.cancel"),
                  color: this.theme == "dark" ? "white" : "dark"
                },
                dark: this.theme == "dark",
                color: this.theme == "dark" ? "white" : "dark"
              })
              .onOk(password => {
                password = password || "";
                this.$gateway.send("wallet", "delete_wallet", { password });
              })
              .onDismiss(() => {})
              .onCancel(() => {});
          } else {
            // no password
            let password = "";
            // if there's no password (password is empty string)
            this.$gateway.send("wallet", "delete_wallet", { password });
          }
        })
        .onCancel(() => {})
        .onDismiss(() => {});
    }
  }
};
</script>

<style lang="scss">
.password-modal {
  min-width: 400px;
  background: white;
  color: #1f1c47;

  > * {
    color: #1f1c47;
  }
}

.rescan-modal {
  background: white;
  color: #1f1c47;
}

.image-path {
  opacity: 0;
  overflow: hidden;
}

.key-image-modal {
  color: #1f1c47;
  background: white;

  label * {
    color: #1f1c47 !important;
    text-overflow: ellipsis;
    overflow: hidden;
  }
  input {
    overflow: ellipsis;
  }
}
.export-transfers-modal {
  color: #1f1c47;
  background: white;
  min-width: 500px;

  label * {
    color: #1f1c47 !important;
    text-overflow: ellipsis;
    overflow: hidden;
  }
  input {
    overflow: ellipsis;
  }
}

.export-transfers-path {
  opacity: 0;
  overflow: hidden;
}

.private-key-modal {
  background: white;
  color: #1f1c47;

  .copy-btn {
    margin-left: 8px;
  }
}

.key-image-modal {
  min-width: 400px;
  width: 45vw;

  .oxen-field {
    flex: 1;
  }
}
</style>
