import { Ajax, Vn, Toast, isTrue, FilePondHandler, mockServer, Log } from "./helper";

const Setup = {
  state: {
    setupStarted: 1,
    currentStep: 1,
    stepScreen: 1,
    steps: [
      "Set Credentials",
      "Set URL",
      "Set ID",
      "Configure Apps Script",
      "Done",
    ],
    no_order: 0,
  },

  osgsw_script: osgsw_script,
  show_notice_popup_setup : false,
  option: {},

  get credentials() {
    return this.option.credentials || {};
  },

  get limit() {
    return this.osgsw_script.limit;
  },

  get is_woocommerce_installed() {
    return isTrue(this.osgsw_script.is_woocommerce_installed);
  },

  get is_woocommerce_activated() {
    return isTrue(this.osgsw_script.is_woocommerce_activated);
  },

  get isPro() {
    return isTrue(this.osgsw_script.is_ultimate_license_activated);
  },

  /**
   * Tabbing
   */
  get step() {
    return this.osgsw_script.options.setup_step || 1;
  },

  isStep(step) {
    return this.state.currentStep === step;
  },
  get isFirstScreen() {
    return this.state.stepScreen === 1;
  },
  get isNoOrder() {
    return this.state.no_order === 1;
  },

  setStep(step) {
    this.state.currentStep = step;
    window.location.hash = `#step-${step}`;
  },

  showPrevButton() {
    return (
      (this.state.currentStep > 1 || !this.isFirstScreen) &&
      this.state.currentStep !== 5
    );
  },


  showNextButton() {
    console.log("Checking if Next button should be shown...");
    if (!this.osgsw_script.is_woocommerce_activated) {
      return false;
    }

    if (this.state.currentStep === 5) {
      return false;
    }

    switch (this.state.currentStep) {
      /**
       * Middleware for step 1
       */
      case 1:
      default:
        if (this.isFirstScreen) {
          return this.option.credentials;
        }

        return this.state.enabled_google_sheet_api || false; 

      /**
       * Middleware for step 2
       */
      case 2:
        let valid = false;

        // check if spreadsheet_url is valid url
        if (this.option.spreadsheet_url) {
          valid = this.option.spreadsheet_url.match(
            /^https:\/\/docs.google.com\/spreadsheets\/d\/[a-zA-Z0-9-_]+\/edit/
          );
        }

        if (!valid) return false;

        return this.option.sheet_tab.trim().length > 0;

      /**
       * Middleware for step 3
       */
      case 3:
        return this.state.given_editor_access || false; 
      /**
       * Middleware for step 4
       */
      case 4:
        if (this.isFirstScreen) {
          return this.state.pasted_apps_script || false;
        }

        return this.state.triggered_apps_script || false; 
    }

    return false;
  },

  prevScreen() {
    if (this.isFirstScreen) {
      this.state.currentStep--;
    }

    this.state.stepScreen = 1;

    this.state.doingPrev = true;
    this.state.doingNext = false;
    this.setStep(this.state.currentStep);
  },

  nextScreen() {
    if (this.isFirstScreen && ![2, 3].includes(this.state.currentStep)) {
      this.state.stepScreen = 2;
    } else {
      this.state.stepScreen = 1;
      this.state.currentStep++;
    }

    this.state.doingNext = true;
    this.state.doingPrev = false;
  },

  clickPreviousButton() {
    this.prevScreen();
  },

  async clickNextButton() {
    let response = null;

    switch (this.state.currentStep) {
      // Set credentials
      case 1:
        if (this.isFirstScreen) {
          let credentials = this.option.credentials;
          response = await Ajax.post("osgsw_update_options", {
            options: {
              credentials: JSON.stringify(credentials),
              credential_file: this.option.credential_file,
              setup_step: 2,
            },
          });
          Log(response);
          if (response.success) {
            this.nextScreen();
          } else {
            Toast.fire({
              icon: "error",
              title: response.message || "Something went wrong",
            });
          }
        } else {
          response = await Ajax.post("osgsw_update_options", {
            options: { setup_step: 2 },
          });
          this.nextScreen();
        }
        break;

      // Set spreadsheet url
      case 2:
        response = await Ajax.post("osgsw_update_options", {
          options: {
            spreadsheet_url: this.option.spreadsheet_url,
            sheet_tab: this.option.sheet_tab,
            setup_step: 3,
          },
        });

        if (response.success) {
          this.nextScreen();
        } else {
          Toast.fire({
            icon: "error",
            title: response.message || "Something went wrong",
          });
        }

        break;

      // Set editor access
      case 3:
        this.state.loadingNext = true;
        response = await Ajax.post("osgsw_init_sheet");
        this.state.loadingNext = false;

        Log("Sheet initialized", response);

        if (response.success) {
          Toast.fire({
            icon: "success",
            title: "Google Sheet is connected", 
          });

          response = await Ajax.post("osgsw_update_options", {
            options: {
              setup_step: 4,
            },
          });

          this.nextScreen();
        } else {
          Toast.fire({
            toast: false,
            showConfirmButton: true,
            timer: false,
            icon: "error",
            title: "Invalid access!",
            html: response.message || "Something went wrong",
            position: "center",
          });
        }

        break;

      // Set apps script
      case 4:
        if (!this.isFirstScreen) {
          response = await Ajax.post("osgsw_update_options", {
            options: {
              setup_step: 5,
            },
          });

          this.nextScreen();
        } else {
          this.nextScreen();
        }

        break;

      default:
        response = await Ajax.post("osgsw_update_options", {
          options: {
            setup_step: this.currentStep + 1,
          },
        });

        this.nextScreen();
        break;
    }
  },

  init() {
    this.osgsw_script = osgsw_script || {};
    this.option = this.osgsw_script.options || {};
    Log(this.osgsw_script);

    if (this.option.setup_step) {
      this.state.setupStarted = true;
      this.state.currentStep = Number(this.option.setup_step);
    } else {
      this.state.setupStarted = false;
      this.state.currentStep = 1;
    }

    // let hash = window.location.hash;
    // if (hash) {
    //   let step = hash.replace("#step-", "");
    //   if (step) {
    //     this.state.currentStep = parseInt(step);
    //     this.state.stepScreen = 1;
    //     this.state.setupStarted = true;
    //   }
    // }

    /**
     * Init FilePond
     */

    this.handleFilePond();

    /**
     * YouTube players
     */
    this.playVideos();
  },

  async activateWooCommerce() {
    if (this.state.activatingWooCommerce) return;

    this.state.activatingWooCommerce = true;

    const response = await Ajax.post("osgsw_activate_woocommerce");

    this.state.activatingWooCommerce = false;

    if (response.success) {
      this.state.activatingWooCommerce = false;
      this.osgsw_script.is_woocommerce_activated = true;
      this.osgsw_script.is_woocommerce_installed = true;
    } else {
      Toast.fire({
        icon: "error",
        title: response.message || "Something went wrong",
      });
    }
  },

  /**
   * Copy Service Account Credentials
   */
  copyServiceAccountEmail() {
    if ("client_email" in this.credentials && this.credentials.client_email) {
      const el = document.createElement("textarea");
      el.value = this.credentials.client_email;
      document.body.appendChild(el);
      el.select();
      document.execCommand("copy");
      document.body.removeChild(el);

      this.state.copied_client_email = true;

      Toast.fire( {
        icon: "success",
        title: "Copied to clipboard",
        }
      );

      setTimeout(() => {
        this.state.copied_client_email = false;
      }, 3000);
    }
  },

  /**
   * Copy Apps Scrips
   */
  copyAppsScript() {
    let script = this.osgsw_script.apps_script;

    script = script.replace("{site_url}", this.osgsw_script.site_url);
    script = script.replace("{token}", this.option.token);
    script = script.replace("{order_statuses}", JSON.parse(this.osgsw_script.order_statuses));
    script = script.replace("{sheet_tab}", this.option.sheet_tab);

    script = script.replace(/\s+/g, " ");

    const el = document.createElement("textarea");
    el.value = script;
    document.body.appendChild(el);
    el.select();
    document.execCommand("copy");
    document.body.removeChild(el);

    this.state.copied_apps_script = true;

    Toast.fire( {
      icon: "success",
      title: "Copied to clipboard",
      }
    );

    setTimeout(() => {
      this.state.copied_apps_script = false;
    }, 3000);
  },

  // handleFilePond
  handleFilePond() {
    this.state.pond = FilePondHandler().create(
      document.querySelector('input[type="file"]'),
      {
        credits: false,
        server: mockServer,
        allowFilePoster: false,
        allowImageEditor: false,
        labelIdle: `<div class="ssgs-upload"><div>Drag and drop the <strong><i>credential.json</i></strong> file here</div> <span>OR</span> <div><span class="upload-button">Upload file</span></div> <div class="ssgs-uploaded-file-name" x-show="option.credential_file || false">
        <svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 16 16">
          <path d="M10.97 4.97a.75.75 0 0 1 1.07 1.05l-3.99 4.99a.75.75 0 0 1-1.08.02L4.324 8.384a.75.75 0 1 1 1.06-1.06l2.094 2.093 3.473-4.425a.267.267 0 0 1 .02-.022z" />
        </svg> <i x-html="option.credential_file"></i> Uploaded
      </div></div>`,
        // restrict to files with the following extensions
        acceptedFileTypes: ["json"],
        maxFiles: 1,
        required: true,
        dropOnPage: true,
      }
    );

    this.state.pond.beforeDropFile = this.beforeDropFile;
    this.state.pond.beforeAddFile = this.beforeDropFile;

    /**
     * Handle file upload
     */
    this.state.pond.on("processfile", (error, file) => {
      if (error) {
        return;
      }

      const reader = new FileReader();

      reader.onload = (e) => {
        const data = JSON.parse(e.target.result);

        Log(data);

        /**
         * Validate credentials
         */

        let isValid = true;

        const required_keys = [
          "client_email",
          "private_key",
          "type",
          "project_id",
          "client_id",
        ];

        required_keys.forEach((key) => {
          if (!data[key]) {
            isValid = false;
          }
        });

        if (isValid) {
          Log("Uploading " + file.filename);
          this.option.credential_file = file.filename;
          this.option.credentials = data;
          this.state.pond.removeFiles();
          this.clickNextButton();
        } else {
          Toast.fire({
            icon: "error",
            title: "Invalid credentials",
          });

          this.state.pond.removeFiles();
        }
      };
      reader.readAsText(file.file);

      // var nextBtn = document.getElementById( "nextBtn" );

      // nextBtn.setAttribute("onclick", "nextPrev(1)");
    });
  },

  /**
   * beforeDropFile
   */
  beforeDropFile: (file) => {
    if (file.file.type !== "application/json") {
      Toast.fire({
        icon: "error",
        title: "Invalid file type",
      });

      Setup.state.pond.removeFiles();
      return false;
    }
    return true;
  },

  /**
   * Sync Google Sheet
   */
  async syncOnGoogleSheet(event) {
    this.state.syncingGoogleSheet = true;
    try {
        if (event) {
            event.preventDefault();
            event.stopPropagation();
        }

        // Initial sync request
        const syncResponse = await Ajax.post("osgsw_sync_sheet");

        console.log(syncResponse);

        this.state.syncingGoogleSheet = false;

        let successCount = 0;
        let errorCount = 0;

        if (syncResponse.success) {
            if (syncResponse.message === "empty") {
                this.state.no_order = 1;
                await Toast.fire({
                    icon: "warning",
                    title: "Currently you have no order to sync.",
                });
                return;
            }

            const batchSize = 1500;
            const totalItems = syncResponse.message;

            let offset = 0;

            // Change button text to show ongoing sync
            this.state.syncingGoogleSheet = true;

            while (offset < totalItems) {
                // Fix: Add isLastBatch flag for setup wizard sync
                const isLastBatch = (offset + batchSize) >= totalItems;
                const batchResponse = await Ajax.post("osgsw_sync_batch_to_sheet", { offset, batchSize, isLastBatch });
                if (batchResponse.success) {
                    const progress = (((offset + batchSize) / totalItems) * 100).toFixed(2);
                    successCount++;

                    // Display modal with progress
                    Vn.fire({
                        position: "center",
                        showConfirmButton: false,
                        allowOutsideClick: false,
                        icon: "info",
                        title: "Syncing Orders to Google Sheet",
                        html: `
                            <div class="ssgsw_progress_bar_wrap">
                                <img src="${osgsw_script.site_url}/wp-admin/images/spinner.gif" alt="Loading..." style="margin-top: -5px; margin-right: 2px;" />
                                <progress id="ssgsw_progress_bar_3" value="${progress}" max="100"></progress>
                                <strong style="margin-left: 3px; margin-top: -2px">${progress}%</strong>
                            </div>
                            <p style="text-align: center"><strong>Please wait...</strong></p>
                        `,
                    });

                    offset += batchSize;
                } else {
                    errorCount++;
                    if (errorCount > 5) {
                      // Skip problematic batch after 5 retries
                        offset += batchSize; 
                    }
                }
            }

            // Handle completion and errors
            if (successCount > 0 && errorCount === 0) {
                Vn.success("All orders successfully synced on Google Sheet!");
                this.nextScreen(); // Redirect to the next page
            } else if (errorCount > 0) {
                Vn.error(`Sync partially completed. ${errorCount} batches failed to sync.`);
            } else {
                Vn.error("Sync failed completely!");
            }
        } else {
            Toast.fire({
                icon: "error",
                title: syncResponse.message || "Something went wrong",
            });
            Vn.error("No orders found to sync.");
            this.nextScreen(); 
        }
    } catch (error) {
        console.error("Error during sync:", error);
        Vn.error("Unexpected error occurred!");
    } finally {
        this.state.syncingGoogleSheet = false;
    }
  },



  /**
   * viewGoogleSheet
   */
  viewGoogleSheet() {
    window.open(this.option.spreadsheet_url, "_blank"); 
  },

  /**
   * Play YouTube videos
   */
  playVideos() {
    const plays = document.querySelectorAll("div[data-play]");
    const getIframe = (videoId) => {
      return `<iframe width="100%" height="315" src="https://www.youtube.com/embed/${videoId}?rel=0" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>`;
    };

    plays.forEach((play) => {
      play.addEventListener("click", (e) => {
        const parent = e.target.closest("div[data-play]");
        let videoUrl = parent.getAttribute("data-play");
        // Log(videoUrl);
        videoUrl = videoUrl.match(
          /(?:https?:\/{2})?(?:w{3}\.)?youtu(?:be)?\.(?:com|be)(?:\/watch\?v=|\/)([^\s&]+)/
        );
        const videoId = videoUrl[1] || "";
        const container = parent.querySelector("div");
        if (container) return;
        parent.innerHTML = getIframe(videoId);
        parent.classList.remove("play-icon");
      });
    });
  },
};

export default () => Setup;
