import axios, { AxiosError, AxiosResponse } from "axios";
import moment from "moment";
import { AnyAction } from "redux";
import { ThunkAction } from "redux-thunk";

import {
    GET_CHECKLIST_FORM_DATA_FAILED,
    GET_CHECKLIST_FORM_DATA_REQUEST,
    GET_CHECKLIST_FORM_DATA_SUCCESS,
    GET_CHECKLIST_SUBMISSIONS_DATA_REQUEST,
    GET_CHECKLIST_SUBMISSIONS_DATA_SUCCESS,
    GET_CHECKLIST_SUBMISSIONS_FAILED,
    SUBMIT_CHECKLIST_FAILED,
    SUBMIT_CHECKLIST_REQUEST,
    SUBMIT_CHECKLIST_SUCCESS,
} from "./types";

import config from '../../config/config';
import { RootState } from "../store";

import { axiosErrorMessage } from "../../utils/helper";


import { addHistory } from "./historyScreenActions";

// Generic API Response type
type ApiResponse<T> = AxiosResponse<T>;

// Image type for uploads
export interface UploadImage {
  uri: string;
  type: string;
  name?: string;
  key?: string;
}

type AppThunk<ReturnType = void> = ThunkAction<
  Promise<ReturnType> | void,
  RootState,
  unknown,
  AnyAction
>;

/**
 * ✅ Fetch Checklist Form Data
 */
export const getCheckListFormData = (): AppThunk => {
  return async (dispatch) => {
    dispatch({ type: GET_CHECKLIST_FORM_DATA_REQUEST });

    try {
      const res: ApiResponse<any> = await axios.get(
        `${config.apiserver}/api/v1/checklist/get-checklist-types-and-locations`
      );

      dispatch({
        type: GET_CHECKLIST_FORM_DATA_SUCCESS,
        payload: res.data,
      });
    } catch (error) {
      console.error("GET_CHECKLIST_FORM_DATA_FAILED", error);
      axiosErrorMessage(
        "Something went wrong while fetching checklist form data. Try to sync again",
        error as AxiosError
      );
      dispatch({
        type: GET_CHECKLIST_FORM_DATA_FAILED,
        payload: error,
      });
    }
  };
};

/**
 * ✅ Fetch Checklist Submissions
 */
export const getCheckListSubmissions = (
  checklistId: number,
  entityId: number,
  type: string
): AppThunk => {
  return async (dispatch, getState) => {
    const { userInfo } = getState();
    const accessToken = userInfo?.userInfo?.access_token;

    const formData = new FormData();
    formData.append("id", checklistId.toString());
    formData.append("entity_id", entityId.toString());
    formData.append("type", type);

    dispatch({ type: GET_CHECKLIST_SUBMISSIONS_DATA_REQUEST });

    try {
      const res: ApiResponse<any> = await axios.post(
        `${config.apiserver}/api/v1/checklist/get-checklist-submissions`,
        formData,
        {
          headers: { Authorization: `Bearer ${accessToken}` },
        }
      );

      dispatch({
        type: GET_CHECKLIST_SUBMISSIONS_DATA_SUCCESS,
        payload: res.data,
      });
    } catch (error) {
      axiosErrorMessage(
        "Something went wrong while fetching checklist submissions.",
        error as AxiosError
      );
      dispatch({
        type: GET_CHECKLIST_SUBMISSIONS_FAILED,
        payload: error,
      });
    }
  };
};

/**
 * ✅ Submit Checklist
 */
export const submitCheckList = (
  data: Record<string, any>,
  formId: string,
  checkListType: string,
  selectedEntity: string,
  checkListTypeId: string,
  checklistSubmissionId: string,
  selectedBUManager: string,
  images: UploadImage[] = []
): AnyAction => {
  const formData = new FormData();
  const keys: string[] = [];
  const allData: Record<string, any> = {
    [formId]: {
      id: checkListTypeId,
      entity_id: selectedEntity,
      checklist_submission_id: checklistSubmissionId,
      checklist_form_type: checkListType,
      selectedBUManager,
    },
  };

  const actions: any[] = [];

  Object.entries(data).forEach(([key, value]) => {
    let questionId = "";

    if (key.includes("_actions") && value?.body?.length > 0) {
      actions.push(value);
    }

    if (key.includes("_answer")) {
      questionId = key.replace("_answer", "");
      allData[formId][questionId] ??= {};
      allData[formId][questionId].composite_radio_webform_custom_composite = value;
    }

    if (key.includes("_observation")) {
      questionId = key.replace("_observation", "");
      allData[formId][questionId] ??= {};
      allData[formId][questionId].composite_textarea_webform_custom_composite = value;
    }

    if (key.includes("_uri") && Array.isArray(value)) {
      questionId = key.replace("_uri", "");
      const filenames: string[] = [];

      value.forEach((img: UploadImage) => {
        const ext =
          img.name?.substring(img.name.lastIndexOf(".") + 1) ??
          (img.type === "video/mp4" ? "mp4" : "jpg");

        const fileName = `${questionId}image${img.key}.${ext}`;
        filenames.push(fileName);

        keys.push(`imageKey_${fileName}`);
        formData.append(`imageKey_${fileName}`, {
          uri: img.uri,
          type: img.type,
          name: fileName,
        } as any);
      });

      allData[formId][questionId] ??= {};
      allData[formId][questionId].composite_file_webform_custom_composite =
        filenames.join();
    }
  });

  allData[formId].actions = actions;
  formData.append("submission_data", JSON.stringify(allData));

  if (keys.length > 0) {
    formData.append("image_keys", keys.join());
  }

  const formattedDate = moment().format("DD-MM-YYYY");
  const formattedTime = moment().format("h:mm:ss a");

  addHistory({
    title: `${formId} has submitted on ${formattedDate} at ${formattedTime}`,
    data: formData,
    url: `${config.apiserver}/api/v1/checklist/webform-submission`,
  });

  return {
    type: SUBMIT_CHECKLIST_REQUEST,
    payload: formData,
    meta: {
      offline: {
        effect: {
          url: `${config.apiserver}/api/v1/checklist/webform-submission`,
          method: "post",
          data: formData,
          headers: { Accept: "*/*" },
        },
        commit: { type: SUBMIT_CHECKLIST_SUCCESS, meta: {} },
        rollback: {
          type: SUBMIT_CHECKLIST_FAILED,
          meta: {
            title: formId,
            url: `${config.apiserver}/api/v1/checklist/webform-submission`,
            data: formData,
          },
        },
      },
    },
  };
};

/**
 * ✅ Validate Checklist Submission
 */
export const checkListSubmissionValidation = (
  id: string,
  entityId: string,
  checklistSubmissionId: string,
  checklistFormType: string
): AppThunk<AxiosResponse | AxiosError> => {
  return async () => {
    const formData = new FormData();
    formData.append("id", id);
    formData.append("entity_id", entityId);
    formData.append("checklist_submission_id", checklistSubmissionId);
    formData.append("checklist_form_type", checklistFormType);

    try {
      const res: ApiResponse<any> = await axios.post(
        `${config.apiserver}/api/v1/checklist/form-submission-validaton`,
        formData
      );
      return res;
    } catch (error) {
      console.error("checkListSubmissionValidation error =>", error);
      return error as AxiosError;
    }
  };
};
