import { StringCaser } from "@/components/WebExportReact/src/utils/helpers";
import { findComponentsWithNavigationProperty } from "../utils/navigation";
let appFragments = [];
let config = null;

export default (fragments, configuration) => {
  appFragments = fragments;
  config = configuration;
  let navigationTemplate = xml(fragments);

  let content = [];

  if (fragments?.length) {
    for (let fragment of fragments) {
      content.push(generateFragmentNavigation(fragment, configuration));
    }
  }

  content.push(generateAuthNavigation(config));

  return navigationTemplate.replace("{{{CONTENT}}}", content.join("\n"));
};

const xml = (fragments) => {
  return `<?xml version="1.0" encoding="utf-8"?>
  <navigation xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto"
      xmlns:tools="http://schemas.android.com/tools"
      android:id="@+id/main_nav"
      app:startDestination="@id/${StringCaser(
        config.hasAuth ? "splash" : config.startDestination ?? "home",
        { casetype: "lowercase" }
      )}">
  
      {{{CONTENT}}}
      

      <!-- ALERTS-->
    <fragment
        android:id="@+id/alerts"
        android:name="${config.packageName}.ui.fragments.alerts.AlertsFragment"
        android:label="fragment_alerts"
        tools:layout="@layout/fragment_alerts"></fragment>
    
  </navigation>
`;
};

const generateFragmentNavigation = (fragment, configuration) => {
  let navElements = findComponentsWithNavigationProperty(fragment);

  const fragmentCamelCaseId = StringCaser(fragment.name, {
    casetype: "camelCase",
  });
  const fragmentCapitalizedName = StringCaser(fragment.name, {
    casetype: "capitalize",
  });
  const fragmentLayout = StringCaser(fragment?.name, {
    casetype: "lowercase",
    separator: "_",
  });
  return `<fragment
  android:id="@+id/${fragmentCamelCaseId}"
  android:name="com.${configuration.name.toLowerCase()}.app.ui.${fragmentCapitalizedName}Fragment"
  android:label="fragment_${fragment.name.toLowerCase()}"
  tools:layout="@layout/fragment_${fragmentLayout}">
    ${buildActions(navElements, fragmentCapitalizedName, configuration)}
    ${buildArgs(fragment, configuration)}
</fragment>`;
};

const buildActions = (actions, fragmentName, configuration) => {
  const uniqueActions = new Set();

  const content = [];
  for (let action of actions) {
    let actionId = "";
    let actionDestination = "";

    switch (action.props.to) {
      case "login":
        actionId = `action_${fragmentName}Fragment_to_loginFragment`;
        actionDestination = "@id/login";
        break;
      case "sign_up":
        actionId = `action_${fragmentName}Fragment_to_signUpFragment`;
        actionDestination = "@id/signUp";
        break;
      case "profile":
        actionId = `action_${fragmentName}Fragment_to_profileFragment`;
        actionDestination = "@id/profile";
        break;
      default:
        let destinationFragment = appFragments.find(
          (frag) => frag.id == action.props.to
        );
        const destinationCapitalized = StringCaser(destinationFragment?.name, {
          casetype: "capitalize",
        });
        const destinationCamelcase = StringCaser(destinationFragment?.name, {
          casetype: "camelCase",
        });
        actionId = `action_${fragmentName}Fragment_to_${destinationCapitalized}Fragment`;
        actionDestination = `@id/${destinationCamelcase}`;
    }

    const actionXML = `<action android:id="@+id/${actionId}" app:destination="${actionDestination}" />`;
    if (!uniqueActions.has(actionXML)) {
      uniqueActions.add(actionXML);
      content.push(actionXML);
    }
  }
  // i need the configuration file to access the appbar
  // do another loop for the appbar since appbar displays on every fragment.
  // check if there is appbar then iterate over it
  // then check it with the unique set
  // then create another action and push

  for (let bar of configuration?.appBar) {
    const destinationCapitalized = StringCaser(bar?.fragment, {
      casetype: "capitalize",
    });
    const destinationCamelcase = StringCaser(bar?.fragment, {
      casetype: "camelCase",
    });
    let actionId = `action_${fragmentName}Fragment_to_${destinationCapitalized}Fragment`;
    // let actionDestination = bar?.fragment;
    let actionDestination = `@id/${destinationCamelcase}`;

    const actionXML = `<action android:id="@+id/${actionId}" app:destination="${actionDestination}" />`;
    if (!uniqueActions.has(actionXML)) {
      uniqueActions.add(actionXML);
      content.push(actionXML);
    }
  }
  return content.join("\n");
};

const buildArgs = (fragment, configuration) => {
  const content = [];

  if (fragment.argument) {
    let destinationFragment = fragment.argument.trim();
    const destinationCapitalized = StringCaser(destinationFragment, {
      casetype: "capitalize",
    });
    content.push(
      ` <argument
      android:name="data"
        app:argType="${configuration.packageName}.data.${destinationCapitalized}Model" />`
    );
  }

  return content.join("\n");
};

const generateAuthNavigation = (configuration) => {
  if (!configuration.hasAuth) return "";

  return `
  <fragment
  android:id="@+id/login"
  android:name="${configuration.packageName}.ui.fragments.LoginFragment"
  android:label="fragment_login"
  tools:layout="@layout/fragment_login">
  <action
      android:id="@+id/action_loginFragment_to_homeFragment"
      app:destination="@id/home"/>
  <action
      android:id="@+id/action_loginFragment_to_signUpFragment"
      app:destination="@id/signUp" />
  <action
      android:id="@+id/action_loginFragment_to_forgetPasswordFragment"
      app:destination="@id/forgetPassword" />
</fragment>

<fragment
    android:id="@+id/forgetPassword"
    android:name="${configuration.packageName}.ui.fragments.ForgetPasswordFragment"
    android:label="fragment_forget_password"
    tools:layout="@layout/fragment_forget_password">

    <action
      android:id="@+id/resetPasswordFragment"
      app:destination="@id/resetPassword" />
</fragment>

<fragment
    android:id="@+id/resetPassword"
    android:name="${configuration.packageName}.ui.fragments.ResetPasswordFragment"
    android:label="fragment_reset_password"
    tools:layout="@layout/fragment_reset_password">

    <action
      android:id="@+id/loginFragment"
      app:destination="@id/login" />
</fragment>

<fragment
  android:id="@+id/signUp"
  android:name="${configuration.packageName}.ui.fragments.SignUpFragment"
  android:label="fragment_sign_up"
  tools:layout="@layout/fragment_sign_up">
  <action
      android:id="@+id/action_signUpFragment_to_homeFragment"
      app:destination="@id/home" />
  <action
      android:id="@+id/action_signUpFragment_to_loginFragment"
      app:destination="@id/login" />
</fragment>

<fragment
      android:id="@+id/profile"
      android:name="${configuration.packageName}.ui.fragments.ProfileFragment"
      android:label="fragment_my_account"
      tools:layout="@layout/fragment_profile">
    
    <action
      android:id="@+id/action_profileFragment_to_profileEditFragment"
      app:destination="@id/profileEdit" />

  </fragment>


  <fragment
        android:id="@+id/profileEdit"
        android:name="${configuration.packageName}.ui.fragments.ProfileEditFragment"
        android:label="fragment_profile_edit"
        tools:layout="@layout/fragment_profile_edit">

    <action
        android:id="@+id/action_profileEditFragment_to_homeFragment"
        app:destination="@id/home" />

    <action
        android:id="@+id/action_profileEditFragment_to_loginFragment"
        app:destination="@id/login" />

    </fragment>

  <fragment
  android:id="@+id/splash"
  android:name="${configuration.packageName}.ui.fragments.SplashFragment"
  android:label="fragment_splash"
  tools:layout="@layout/fragment_splash">
  <action
      android:id="@+id/action_splashFragment_to_loginFragment"
      app:destination="@id/login" />
  <action
      android:id="@+id/action_splashFragment_to_signUpFragment"
      app:destination="@id/signUp" />
  <action
      android:id="@+id/action_splashFragment_to_homeFragment"
      app:destination="@id/home" />
</fragment>
  
  `;
};
