// src/actions/commonActions.js

import { Job } from "@enact/core/util";
import Spotlight from "@enact/spotlight";

import appinfo from "../../webos-meta/appinfo.json";
import appinfo35 from "../../webos-meta/appinfo35.json";
import appinfo79 from "../../webos-meta/appinfo79.json";
import { handleBypassLink } from "../App/bypassLinkHandler";
import * as lunaSend from "../lunaSend";
import { initialLocalSettings } from "../reducers/localSettingsReducer";
import * as Config from "../utils/Config";
import * as HelperMethods from "../utils/helperMethods";
import { types } from "./actionTypes";

export const changeAppStatus = (status) => ({
  type: types.CHANGE_APP_STATUS,
  payload: status,
});
export const changeBroadcastEvent = (status) => ({
  type: types.SEND_BROADCAST,
  payload: status,
});

export const changeLocalSettings = (status) => ({
  type: types.CHANGE_LOCAL_SETTINGS,
  payload: status,
});

export const gnbOpened = (status) => ({
  type: types.GNB_OPENED,
  payload: status,
});

export const setShowPopup = (config) => {
  const payload = typeof config === "string" ? { activePopup: config } : config;
  return {
    type: types.SET_SHOW_POPUP,
    payload,
  };
};

export const setShowSecondaryPopup = (popupType, payload = {}) => ({
  type: types.SET_SHOW_SECONDARY_POPUP,
  payload: { activePopup: popupType, ...payload },
});

export const setHidePopup = () => ({
  type: types.SET_HIDE_POPUP,
});

export const setHideSecondaryPopup = () => ({
  type: types.SET_HIDE_SECONDARY_POPUP,
});

export const showOptionalTermsConfirmPopup = () => ({
  type: types.SHOW_OPTIONAL_TERMS_CONFIRM_POPUP,
});

export const hideOptionalTermsConfirmPopup = () => ({
  type: types.HIDE_OPTIONAL_TERMS_CONFIRM_POPUP,
});

export const toggleOptionalTermsConfirm = (selected) => ({
  type: types.TOGGLE_OPTIONAL_TERMS_CONFIRM,
  payload: selected,
});

export const setExitApp = () => (dispatch, getState) => {
  dispatch({ type: types.SET_EXIT_APP });

  console.log("Exiting App...");

  if (typeof window === "object") {
    window.close();
  } else {
    window.location.reload();
  }
};

export const getLoginUserData = (userData) => ({
  type: types.GET_LOGIN_USER_DATA,
  payload: userData,
});

export const loadingComplete = (status) => ({
  type: "loadingComplete",
  payload: status,
});

export const alertToast = (payload) => (dispatch, getState) => {
  if (typeof window === "object" && !window.PalmSystem) {
    dispatch(changeAppStatus({ toast: true, toastText: payload }));
  } else {
    lunaSend.createToast(payload);
  }
};

export const getSystemSettings = () => (dispatch, getState) => {
  console.log("getSystemSettings ");
  lunaSend.getSystemSettings(
    { category: "caption", keys: ["captionEnable"] },
    {
      onSuccess: (res) => {},
      onFailure: (err) => {},
      onComplete: (res) => {
        console.log("getSystemSettings onComplete", res);
        if (res && res.settings) {
          if (typeof res.settings.captionEnable !== "undefined") {
            dispatch(
              changeAppStatus({
                captionEnable:
                  res.settings.captionEnable === "on" ||
                  res.settings.captionEnable === true,
              })
            );
          }
        }
      },
    }
  );
};

export const getHttpHeaderForServiceRequest =
  (onComplete) => (dispatch, getState) => {
    console.log("getHttpHeaderForServiceRequest ");
    const { serverType, ricCodeSetting, languageSetting } =
      getState().localSettings;
    lunaSend.getHttpHeaderForServiceRequest({
      onSuccess: (res) => {
        const version = res["X-Device-Netcast-Platform-Version"] || "";
        const webOSVersion = Number(
          version.substring(0, version.lastIndexOf("."))
        );

        // 4버전 미만인 경우 다른 처리 없이 버전 정보만 저장
        if (webOSVersion < 4) {
          dispatch(
            changeAppStatus({
              webOSVersion,
              showLoadingPanel: { show: false },
            })
          );
          return;
        }

        // 4버전 이상인 경우 기존 로직 수행
        console.log("getHttpHeaderForServiceRequest", res);
        const convertedRes = {
          Authorization: res["Authorization"],
          "X-Authentication": res["X-Authentication"],
          "X-Device-ID": res["X-Device-ID"],
          "X-Device-Product": res["X-Device-Product"],
          "X-Device-Platform": res["X-Device-Platform"],
          "X-Device-Model": res["X-Device-Model"],
          "X-Device-Eco-Info": res["X-Device-Eco-Info"],
          "X-Device-Country": res["X-Device-Country"],
          "X-Device-Language": res["X-Device-Language"],
          "X-Device-Netcast-Platform-Version":
            res["X-Device-Netcast-Platform-Version"],
          "X-Device-Publish-Flag": res["X-Device-Publish-Flag"],
          "X-Device-Fck": res["X-Device-Fck"],
          "X-Device-Eula": res["X-Device-Eula"],
          "X-Device-SDK-VERSION": res["X-Device-SDK-VERSION"],
        };
        convertedRes["X-Device-Personalization"] = "Y";

        if (
          typeof window === "object" &&
          window.PalmSystem &&
          window.PalmSystem.identifier &&
          process.env.REACT_APP_MODE !== "DEBUG"
        ) {
          convertedRes["app_id"] = window.PalmSystem.identifier ?? appinfo.id;
        } else {
          if (ricCodeSetting === "aic") {
            convertedRes["app_id"] = appinfo.id;
          } else if (ricCodeSetting === "eic") {
            convertedRes["app_id"] = appinfo35.id;
          } else if (ricCodeSetting === "ruc") {
            convertedRes["app_id"] = appinfo79.id;
          } else {
            convertedRes["app_id"] = appinfo.id;
          }
        }

        convertedRes["app_ver"] = "1.0.0";
        convertedRes["cntry_cd"] = res["X-Device-Country"];
        convertedRes["prod_cd"] = res["X-Device-Product"];
        convertedRes["plat_cd"] = res["X-Device-Platform"];
        convertedRes["lang_cd"] = res["X-Device-Language"];
        convertedRes["sdk_ver"] = res["X-Device-SDK-VERSION"];
        convertedRes["publish_flag"] = res["X-Device-Publish-Flag"];
        convertedRes["os_ver"] = version;
        convertedRes["dvc_auth"] = res["X-Authentication"];

        if (serverType !== "system") {
          if (ricCodeSetting === "eic") {
            if (languageSetting === "GB") {
              convertedRes["cntry_cd"] = "GB";
              convertedRes["X-Device-Country"] = "GB";
              res["HOST"] = "GB.nextlgsdp.com";
            }
            if (languageSetting === "DE") {
              convertedRes["cntry_cd"] = "DE";
              convertedRes["X-Device-Country"] = "DE";
              res["HOST"] = "DE.nextlgsdp.com";
            }
          }
          if (ricCodeSetting === "aic") {
            convertedRes["cntry_cd"] = "US";
            convertedRes["X-Device-Country"] = "US";
            res["HOST"] = "US.nextlgsdp.com";
          }
          if (ricCodeSetting === "ruc") {
            convertedRes["cntry_cd"] = "RU";
            convertedRes["X-Device-Country"] = "RU";
            res["HOST"] = "RU.nextlgsdp.com";
          }
        }

        if (convertedRes["cntry_cd"] === "US") {
          convertedRes["lang_cd"] = "en-US";
        }
        if (convertedRes["cntry_cd"] === "DE") {
          convertedRes["lang_cd"] = "de-DE";
        }
        if (convertedRes["cntry_cd"] === "GB") {
          convertedRes["lang_cd"] = "en-GB";
        }
        if (convertedRes["cntry_cd"] === "RU") {
          convertedRes["lang_cd"] = "ru-RU";
        }

        dispatch({ type: types.GET_HTTP_HEADER, payload: convertedRes });
        dispatch(
          changeAppStatus({
            webOSVersion,
            serverHOST: res["HOST"],
            mbr_no: res["X-User-Number"],
          })
        );

        const parameters = { serviceName: "LGE" };
        const mbrNo = res["X-User-Number"];

        lunaSend.getLoginUserData(parameters, {
          onSuccess: (res) => {
            const userId = res.id ?? "";
            const userNumber = res.lastSignInUserNo;
            const profileNick = res.profileNick || userId.split("@")[0];
            dispatch(
              getLoginUserData({
                userId,
                userNumber: mbrNo,
                profileNick,
              })
            );
          },
          onFailure: (err) => console.error("LoginData fetch failed ", err),
        });
      },
      onFailure: (err) => {
        console.log("getHttpHeaderForServiceRequest fail", err);
      },
    });
  };

export const getDeviceId = (onComplete) => (dispatch, getState) => {
  lunaSend.getDeviceId(
    { idType: ["LGUDID"] },
    {
      onSuccess: (res) => {
        console.log("getDeviceId ", res);
        if (res.returnValue) {
          const deviceId = res.idList[0].idValue;
          dispatch(changeAppStatus({ deviceId: deviceId }));
        }
      },
      onFailure: (err) => {
        console.log(err);
      },
      onComplete: () => {
        console.log("getDeviceId done");
        if (onComplete) onComplete();
      },
    }
  );
};

export const getTermsAgreeYn = () => (dispatch, getState) => {
  dispatch({ type: types.GET_TERMS_AGREE_YN_START });

  try {
    const { terms } = getState().home.termsData.data;

    console.log(
      "getTermsAgreeYn",
      terms.map((term) => ({
        trmsId: term.trmsId,
        trmsTpCd: term.trmsTpCd,
        trmsAgrFlag: term.trmsAgrFlag,
        trmsPopFlag: term.trmsPopFlag,
      }))
    );

    // MST00405 선택약관 정보만 따로 출력
    const optionalTerm = terms.find((term) => term.trmsTpCd === "MST00405");
    if (optionalTerm) {
      console.log("getTermsAgreeYn MST00405 선택약관:", {
        trmsId: optionalTerm.trmsId,
        trmsTpCd: optionalTerm.trmsTpCd,
        trmsAgrFlag: optionalTerm.trmsAgrFlag,
        trmsPopFlag: optionalTerm.trmsPopFlag,
      });
    } else {
      console.log("getTermsAgreeYn MST00405 선택약관을 찾을 수 없습니다.");
    }

    const termsAgreeFlag = terms.reduce((acc, term) => {
      switch (term.trmsTpCd) {
        case "MST00401":
          acc.privacyTerms = term.trmsAgrFlag;
          break;
        case "MST00402":
          acc.serviceTerms = term.trmsAgrFlag;
          break;
        case "MST00403":
          acc.purchaseTerms = term.trmsAgrFlag;
          break;
        case "MST00404":
          acc.paymentTerms = term.trmsAgrFlag;
          break;
        case "MST00405":
          acc.optionalTerms = term.trmsAgrFlag;
          break;
        default:
          break;
      }
      return acc;
    }, {});

    dispatch({
      type: types.GET_TERMS_AGREE_YN_SUCCESS,
      payload: termsAgreeFlag,
    });
  } catch (error) {
    console.error("getTermsAgreeYn error:", error);
    dispatch({ type: types.GET_TERMS_AGREE_YN_FAILURE });
  }
};

// export const getTermsAgreeYn = () => (dispatch, getState) => {
//   const { terms } = getState().home.termsData.data;

//   // console.log("getTermsAgreeYn", terms);
//   console.log("getTermsAgreeYn", terms.map(term => ({
//     trmsId: term.trmsId,
//     trmsTpCd: term.trmsTpCd,
//     trmsAgrFlag: term.trmsAgrFlag,
//     trmsPopFlag: term.trmsPopFlag,
//    })));

//   const termsAgreeFlag = terms.reduce((acc, term) => {
//     switch (term.trmsTpCd) {
//       case "MST00401":
//         acc.privacyTerms = term.trmsAgrFlag;
//         break;

//       case "MST00402":
//         acc.serviceTerms = term.trmsAgrFlag;
//         break;

//       case "MST00403":
//         acc.purchaseTerms = term.trmsAgrFlag;
//         break;

//       case "MST00404":
//         acc.paymentTerms = term.trmsAgrFlag;
//         break;

//       case "MST00405":
//         acc.optionalTerms = term.trmsAgrFlag;
//         break;

//       default:
//         break;
//     }

//     return acc;
//   }, {});

//   dispatch({
//     type: types.GET_TERMS_AGREE_YN,
//     payload: termsAgreeFlag,
//   });
// };

export const launchMembershipApp = () => (dispatch, getState) => {
  const state = getState();
  const panels = state.panels.panels;
  const currentPanel = panels[panels.length - 1];

  const returnPath = JSON.stringify({
    name: currentPanel.name,
    panelInfo: currentPanel.panelInfo || {},
  });

  if (typeof window === "object" && !window.PalmSystem) {
    // const testBypass = {
    //   name: Config.panel_names.CATEGORY_PANEL,
    //   panelInfo: {
    //     COUNT: 31,
    //     currentSpot: null,
    //     dropDownTab: 0,
    //     expsOrd: 1,
    //     focusedContainerId: null,
    //     lgCatCd: "1017",
    //     lgCatNm: "LG Electronics",
    //     tab: 0,
    //   },
    // };

    console.log("returnPath", returnPath);
    // setTimeout(() => {
    //   dispatch(handleBypassLink(JSON.stringify(testBypass)));
    // }, 1000);
    return;
  }

  lunaSend.launchMembershipApp(returnPath, {
    onSuccess: (res) => {
      console.log("membership launch success: ", res);
    },
    onFailure: (err) => {
      console.log("membership launch failed:", err);
    },
  });
};

let rafId = null;
export const setFocus = (spotlightId) => ({
  type: types.SET_FOCUS,
  payload: spotlightId,
});

export const focusElement = (spotlightId) => (dispatch, getState) => {
  dispatch(setFocus(spotlightId));

  if (typeof window === "object") {
    rafId = window.requestAnimationFrame(() => {
      Spotlight.focus(spotlightId);
    });
  }
};

export const cancelFocusElement = () => () => {
  if (rafId !== null) {
    if (typeof window === "object") {
      window.cancelAnimationFrame(rafId);
      rafId = null;
    }
  }
};

let broadcastTimer = null;
export const sendBroadCast =
  ({ type, moreInfo }) =>
  (dispatch, getState) => {
    clearTimeout(broadcastTimer);
    dispatch(changeBroadcastEvent({ type, moreInfo }));
    broadcastTimer = setTimeout(() => {
      //clear after 500ms
      dispatch(changeBroadcastEvent({}));
    }, 5000);
  };

export const requestLiveSubtitle =
  ({ mediaId, enable }) =>
  (dispatch, getState) => {
    const webOSVersion = getState().common.appStatus.webOSVersion;

    if (Number(webOSVersion) <= 4.5) {
      lunaSend.setSubtitleEnable(mediaId, enable, {
        onSuccess: (res) => {
          console.log(res);
        },
        onFailure: (err) => {
          console.log(err);
        },
      });
      return;
    } else {
      lunaSend.setSubtitleEnableOver5(mediaId, enable, {
        onSuccess: (res) => {
          console.log(res);
        },
        onFailure: (err) => {
          console.log(err);
        },
      });
    }
  };

export const addReservation = (data) => (dispatch) => {
  lunaSend.addReservation(data, {
    onSuccess: (res) => {
      console.log("addReservation success:", res);
      // Optionally show success toast
      if (res && res.returnValue) {
        dispatch(alertToast("Reminder set successfully"));
      }
    },
    onFailure: (err) => {
      console.error("addReservation failed:", err);
      // Use the helper function for better error handling
      const errorMessage = HelperMethods.getReservationErrorMessage(err);
      dispatch(alertToast(errorMessage));
    },
    onComplete: () => {
      console.log("addReservation completed");
    },
  });
};

export const deleteReservationCallback = (scheduleIdList) => (dispatch) => {
  lunaSend.deleteReservationCallback(scheduleIdList, {
    onSuccess: (res) => {
      // dispatch(alertToast("success" + JSON.stringify(res)));
    },
    onFailure: (err) => {
      // dispatch(alertToast("failed" + JSON.stringify(err)));
    },
  });
};

export const deleteReservation = (showId) => (dispatch) => {
  lunaSend.deleteReservation({
    onSuccess: (res) => {
      let items = [];

      res.results.forEach((item) => {
        let obj = JSON.parse(item.information.information);
        items.push({
          _id: item._id,
          showId: obj.showId,
        });
      });

      let index = items.findIndex((item) => item.showId === showId);

      let deletedIdList = [];
      if (index !== -1) {
        deletedIdList.push(items[index]._id);
        dispatch(deleteReservationCallback(deletedIdList));
      }
    },
    onFailure: (err) => {
      console.log(err);
    },
  });
};

export const setSystemNotice = () => ({
  type: types.SET_SYSTEM_NOTICE,
});

export const setSystemTermination = (isinitialLoad) => ({
  type: types.SET_SYSTEM_TERMINATION,
  payload: { isinitialLoad },
});

export const setDeepLink = (deepLinkInfo) => ({
  type: types.SET_DEEP_LINK,
  payload: deepLinkInfo,
});

export const setSecondLayerInfo = (secondLayerInfo) => ({
  type: types.SET_SECOND_LAYER_INFO,
  payload: secondLayerInfo,
});

export const setGNBMenu = (gnbMenu) => ({
  type: types.SET_GNB_MENU,
  payload: gnbMenu,
});

export const setDeviceRegistered = (isRegistered) => ({
  type: types.SET_DEVICE_REGISTERED,
  payload: isRegistered,
});

export const clearErrorMessage = () => ({
  type: types.CLEAR_ERROR_MESSAGE,
});

export const showError =
  (
    errorCode,
    errorMsg,
    shouldPopPanel = false,
    retDetailCode = null,
    returnBindStrings = null
  ) =>
  (dispatch) => {
    dispatch(
      setShowPopup(Config.ACTIVE_POPUP.errorPopup, {
        data: {
          errorCode,
          errorMsg,
          retDetailCode,
          shouldPopPanel,
          returnBindStrings,
        },
      })
    );
  };

//luna-send -f -n 1 luna://com.webos.service.db/delKind '{"id": "com.lgshop.app:5"}' -a "com.lgshop.app"
export const deleteOldDb8Datas = () => (dispatch) => {
  for (let i = 1; i < 10; i++) {
    lunaSend.deleteOldDb8(i, {
      onSuccess: (res) => {},
      onFailure: (err) => {},
    });
  }
  dispatch(changeLocalSettings({ oldDb8Deleted: true }));
};

export const checkFirstLaunch = () => (dispatch) => {
  lunaSend.checkFirstLaunch({
    onSuccess: (res) => {
      if (!res.returnValue) {
        console.error("Failed to check first launch status");
        return;
      }

      if (res.results.length === 0) {
        console.log("First launch detected - initializing localStorage");

        if (typeof window === "object") {
          dispatch(changeLocalSettings({ phoneNumbers: {}, recentItems: [] }));
        }

        lunaSend.saveFirstLaunchInfo({
          onSuccess: (saveRes) => {
            console.log("First launch info saved to DB8:", saveRes);
            dispatch(changeAppStatus({ isFirstLaunch: true }));
          },
          onFailure: (err) => {
            console.error("Failed to save first launch info:", err);
          },
        });
      } else {
        console.log("Not first launch - keeping existing settings");

        dispatch(changeAppStatus({ isFirstLaunch: false }));
      }
    },
    onFailure: (err) => {
      console.error("Failed to check first launch:", err);
    },
  });
};

let updateNetworkStateJob = new Job((dispatch, connected) => {
  dispatch(changeAppStatus({ isInternetConnected: connected }));
});

export const getConnectionStatus = () => (dispatch, getState) => {
  lunaSend.getConnectionStatus({
    onSuccess: (res) => {
      console.log("lunasend getConnectionStatus", res);
      if (res.returnValue) {
        const isInternet =
          (res.wifi && res.wifi.onInternet === "yes") ||
          (res.wired && res.wired.onInternet === "yes");
        const isInternetConnected =
          (res.wifi && res.wifi.state === "connected") ||
          (res.wired && res.wired.state === "connected");

        console.log(
          "internetconnected.............",
          isInternet,
          isInternetConnected,
          res
        );

        const connected = isInternet && isInternetConnected;

        updateNetworkStateJob.startAfter(
          connected ? 100 : 3000,
          dispatch,
          connected
        );
      }
    },
    onFailure: (err) => {
      console.log(err);
    },
    onComplete: (res) => {
      console.log("getConnectionStatus done", res);
    },
  });
};

// macAddress
export const getConnectionInfo = () => (dispatch, getState) => {
  lunaSend.getConnectionInfo({
    onSuccess: (res) => {
      console.log("lunasend getConnectionStatus", res);
      if (res && res.returnValue) {
        const macAddress = res?.wiredInfo?.macAddress;
        console.log("macAddress...........", macAddress, res);
      }
    },
    onFailure: (err) => {
      console.log("getConnentionInfo", err);
    },
    onComplete: (res) => {
      console.log("getConnentionInfo done", res);
      dispatch({
        type: types.GET_DEVICE_MACADDRESS,
        payload: res,
      });
    },
  });
};

export const disableNotification = () => (dispatch, getState) => {
  lunaSend.disableNotification({
    onSuccess: (res) => {
      console.log("lunasend disable notification success", res);
    },
    onFailure: (err) => {
      console.log("lunasend disable notification failure", err);
    },
    onComplete: (res) => {
      console.log("lunasend disable notification complete", res);
    },
  });
};

export const enableNotification = () => (dispatch, getState) => {
  lunaSend.enableNotification({
    onSuccess: (res) => {
      console.log("lunasend enable notification success", res);
    },
    onFailure: (err) => {
      console.log("lunasend enable notification failure", err);
    },
    onComplete: (res) => {
      console.log("lunasend enable notification complete", res);
    },
  });
};

// 선택약관 팝업 상태 관리 액션 생성자들 (TV 환경 최적화)
export const setOptionalTermsPopupShown = (shown = true) => ({
  type: types.SET_OPTIONAL_TERMS_POPUP_SHOWN,
  payload: shown,
});

export const setOptionalTermsUserDecision = (decision) => ({
  type: types.SET_OPTIONAL_TERMS_USER_DECISION,
  payload: decision, // 'agreed' | 'declined' | null
});

export const resetOptionalTermsSession = () => ({
  type: types.RESET_OPTIONAL_TERMS_SESSION,
});

// 선택약관 동의 처리를 위한 헬퍼 함수
export const handleOptionalTermsAgree = () => (dispatch) => {
  console.log("[CommonActions] 선택약관 동의 처리");
  dispatch(setOptionalTermsUserDecision("agreed"));
  dispatch(setOptionalTermsPopupShown(true));
};

// 선택약관 거절 처리를 위한 헬퍼 함수
export const handleOptionalTermsDecline = () => (dispatch) => {
  console.log("[CommonActions] 선택약관 거절 처리");
  dispatch(setOptionalTermsUserDecision("declined"));
  dispatch(setOptionalTermsPopupShown(true));
};

// 선택약관 상태 통합 업데이트 (TV 환경 최적화 - API 호출 없이 즉시 반영)
export const updateOptionalTermsAgreement =
  (agreed = true) =>
  (dispatch) => {
    console.log(`[CommonActions] 선택약관 통합 상태 업데이트: ${agreed}`);

    // 1. optionalTermsPopupFlow 업데이트 (TV 환경용)
    dispatch(setOptionalTermsUserDecision(agreed ? "agreed" : "declined"));
    dispatch(setOptionalTermsPopupShown(true));

    // 2. 기본 optionalTermsAgree 상태 직접 업데이트 (API 호출 없이)
    dispatch({
      type: types.UPDATE_OPTIONAL_TERMS_AGREE_DIRECT,
      payload: agreed,
    });

    // 3. termsAgreementStatus도 동기화
    dispatch({
      type: types.UPDATE_TERMS_AGREEMENT_STATUS_DIRECT,
      payload: { MST00405: agreed },
    });
  };
