import {
  GOOGLE_DRIVE_NOTIFICATION_ADD,
  GOOGLE_DRIVE_NOTIFICATION_CHANGE,
  GOOGLE_DRIVE_NOTIFICATION_UPDATE,
} from "../../common/constants.mjs";
import commonDedupeChanges from "../common-dedupe-changes.mjs";
import common from "../common-webhook.mjs";
import { stashFile } from "../../common/utils.mjs";
import sampleEmit from "./test-event.mjs";
const { googleDrive } = common.props;
export default {
  ...common,
  key: "google_drive-new-or-modified-files",
  name: "New or Modified Files (Instant)",
  description: "Emit new event when a file in the selected Drive is created, modified or trashed.",
  version: "0.4.1",
  type: "source",
  
  
  dedupe: "unique",
  props: {
    ...common.props,
    folders: {
      type: "string[]",
      label: "Folder(s)",
      description:
        "The folder(s) to watch for changes. Leave blank to watch for any new or modified file in the Drive.",
      optional: true,
      default: [],
      options({ prevContext }) {
        const { nextPageToken } = prevContext;
        const baseOpts = {
          q: "mimeType = 'application/vnd.google-apps.folder' and trashed = false",
        };
        const opts = this.isMyDrive()
          ? baseOpts
          : {
            ...baseOpts,
            corpora: "drive",
            driveId: this.getDriveId(),
            includeItemsFromAllDrives: true,
            supportsAllDrives: true,
          };
        return this.googleDrive.listFilesOptions(nextPageToken, opts);
      },
    },
    watchForPropertiesChanges: {
      propDefinition: [
        googleDrive,
        "watchForPropertiesChanges",
      ],
    },
    includeLink: {
      label: "Include Link",
      type: "boolean",
      description: "Upload file to your File Stash and emit temporary download link to the file. Google Workspace documents will be converted to PDF. See [the docs](https://pipedream.com/docs/connect/components/files) to learn more about working with files in Pipedream.",
      default: false,
      optional: true,
    },
    dir: {
      type: "dir",
      accessMode: "write",
      optional: true,
    },
    ...commonDedupeChanges.props,
  },
  hooks: {
    async deploy() {
      const daysAgo = new Date();
      daysAgo.setDate(daysAgo.getDate() - 30);
      const timeString = daysAgo.toISOString();
      const args = this.getListFilesOpts({
        q: `mimeType != "application/vnd.google-apps.folder" and modifiedTime > "${timeString}" and trashed = false`,
        fields: "files",
        pageSize: 5,
      });
      const { files } = await this.googleDrive.listFilesInPage(null, args);
      await this.processChanges(files);
    },
    ...common.hooks,
  },
  methods: {
    ...common.methods,
    shouldProcess(file) {
      if (file.mimeType !== "application/vnd.google-apps.folder") {
        const watchedFolders = new Set(this.folders);
        return (
          watchedFolders.size == 0 ||
          (file.parents && file.parents.some((p) => watchedFolders.has(p)))
        );
      }
    },
    getUpdateTypes() {
      return [
        GOOGLE_DRIVE_NOTIFICATION_ADD,
        GOOGLE_DRIVE_NOTIFICATION_CHANGE,
        GOOGLE_DRIVE_NOTIFICATION_UPDATE,
      ];
    },
    generateMeta(data, headers) {
      const {
        id: fileId,
        name: summary,
        modifiedTime: tsString,
      } = data;
      const ts = Date.parse(tsString);
      const eventId = headers && headers["x-goog-message-number"];
      return {
        id: `${fileId}-${eventId || ts}`,
        summary,
        ts,
      };
    },
    async getChanges(headers) {
      if (!headers) {
        return {
          change: { },
        };
      }
      const resourceUri = headers["x-goog-resource-uri"];
      const metadata = await this.googleDrive.getFileMetadata(`${resourceUri}&fields=*`);
      return {
        ...metadata,
        change: {
          state: headers["x-goog-resource-state"],
          resourceURI: headers["x-goog-resource-uri"],
          changed: headers["x-goog-changed"], 
        },
      };
    },
    async processChanges(changedFiles, headers) {
      const changes = await this.getChanges(headers);
      const filteredFiles = this.checkMinimumInterval(changedFiles);
      for (const file of filteredFiles) {
        file.parents = (await this.googleDrive.getFile(file.id, {
          fields: "parents",
        })).parents;
        console.log(file); 
        if (!this.shouldProcess(file)) {
          console.log(`Skipping file ${file.name}`);
          continue;
        }
        const eventToEmit = {
          file,
          ...changes,
        };
        if (this.includeLink) {
          eventToEmit.fileURL = await stashFile(file, this.googleDrive, this.dir);
        }
        const meta = this.generateMeta(file, headers);
        this.$emit(eventToEmit, meta);
      }
    },
  },
  sampleEmit,
};