"use client";

import Image from "next/image";
import { useEffect, useMemo, useState } from "react";
import { useForm } from "react-hook-form";
import toast from "react-hot-toast";
import { useTranslation } from "react-i18next";
import {
  TIntegrationGoogleSheets,
  TIntegrationGoogleSheetsConfigData,
  TIntegrationGoogleSheetsInput,
} from "@formbricks/types/integration/google-sheet";
import { TSurvey, TSurveyQuestionId } from "@formbricks/types/surveys/types";
import { getTextContent } from "@formbricks/types/surveys/validation";
import { createOrUpdateIntegrationAction } from "@/app/(app)/environments/[environmentId]/workspace/integrations/actions";
import { getSpreadsheetNameByIdAction } from "@/app/(app)/environments/[environmentId]/workspace/integrations/google-sheets/actions";
import {
  constructGoogleSheetsUrl,
  extractSpreadsheetIdFromUrl,
  isValidGoogleSheetsUrl,
} from "@/app/(app)/environments/[environmentId]/workspace/integrations/google-sheets/lib/util";
import GoogleSheetLogo from "@/images/googleSheetsLogo.png";
import {
  GOOGLE_SHEET_INTEGRATION_INSUFFICIENT_PERMISSION,
  GOOGLE_SHEET_INTEGRATION_INVALID_GRANT,
} from "@/lib/googleSheet/constants";
import { getFormattedErrorMessage } from "@/lib/utils/helper";
import { recallToHeadline } from "@/lib/utils/recall";
import { getElementsFromBlocks } from "@/modules/survey/lib/client-utils";
import { AdditionalIntegrationSettings } from "@/modules/ui/components/additional-integration-settings";
import { Button } from "@/modules/ui/components/button";
import { Checkbox } from "@/modules/ui/components/checkbox";
import {
  Dialog,
  DialogBody,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/modules/ui/components/dialog";
import { DropdownSelector } from "@/modules/ui/components/dropdown-selector";
import { Input } from "@/modules/ui/components/input";
import { Label } from "@/modules/ui/components/label";

interface AddIntegrationModalProps {
  environmentId: string;
  open: boolean;
  surveys: TSurvey[];
  setOpen: (v: boolean) => void;
  googleSheetIntegration: TIntegrationGoogleSheets;
  selectedIntegration?: (TIntegrationGoogleSheetsConfigData & { index: number }) | null;
}

export const AddIntegrationModal = ({
  environmentId,
  surveys,
  open,
  setOpen,
  googleSheetIntegration,
  selectedIntegration,
}: AddIntegrationModalProps) => {
  const { t } = useTranslation();
  const integrationData: TIntegrationGoogleSheetsConfigData = {
    spreadsheetId: "",
    spreadsheetName: "",
    surveyId: "",
    surveyName: "",
    elementIds: [""],
    elements: "",
    createdAt: new Date(),
  };
  const { handleSubmit } = useForm();
  const [selectedElements, setSelectedElements] = useState<string[]>([]);
  const [isLinkingSheet, setIsLinkingSheet] = useState(false);
  const [selectedSurvey, setSelectedSurvey] = useState<TSurvey | null>(null);
  const [spreadsheetUrl, setSpreadsheetUrl] = useState("");
  const [isDeleting, setIsDeleting] = useState<boolean>(false);
  const existingIntegrationData = googleSheetIntegration?.config?.data;
  const [includeVariables, setIncludeVariables] = useState(false);
  const [includeHiddenFields, setIncludeHiddenFields] = useState(false);
  const [includeMetadata, setIncludeMetadata] = useState(false);
  const [includeCreatedAt, setIncludeCreatedAt] = useState(true);
  const googleSheetIntegrationData: TIntegrationGoogleSheetsInput = {
    type: "googleSheets",
    config: {
      key: googleSheetIntegration?.config?.key,
      email: googleSheetIntegration.config.email,
      data: existingIntegrationData || [],
    },
  };

  const surveyElements = useMemo(
    () => (selectedSurvey ? getElementsFromBlocks(selectedSurvey.blocks) : []),
    [selectedSurvey]
  );

  useEffect(() => {
    if (selectedSurvey && !selectedIntegration) {
      const elementIds = surveyElements.map((element) => element.id);
      setSelectedElements(elementIds);
    }
  }, [surveyElements, selectedIntegration, selectedSurvey]);

  useEffect(() => {
    if (selectedIntegration) {
      setSpreadsheetUrl(constructGoogleSheetsUrl(selectedIntegration.spreadsheetId));
      setSelectedSurvey(
        surveys.find((survey) => {
          return survey.id === selectedIntegration.surveyId;
        })!
      );
      setSelectedElements(selectedIntegration.elementIds);
      setIncludeVariables(!!selectedIntegration.includeVariables);
      setIncludeHiddenFields(!!selectedIntegration.includeHiddenFields);
      setIncludeMetadata(!!selectedIntegration.includeMetadata);
      setIncludeCreatedAt(!!selectedIntegration.includeCreatedAt);
      return;
    } else {
      setSpreadsheetUrl("");
    }
    resetForm();
  }, [selectedIntegration, surveys]);

  const showErrorMessageToast = (response: Awaited<ReturnType<typeof getSpreadsheetNameByIdAction>>) => {
    const errorMessage = getFormattedErrorMessage(response);
    if (errorMessage === GOOGLE_SHEET_INTEGRATION_INVALID_GRANT) {
      toast.error(t("environments.integrations.google_sheets.token_expired_error"));
    } else if (errorMessage === GOOGLE_SHEET_INTEGRATION_INSUFFICIENT_PERMISSION) {
      toast.error(t("environments.integrations.google_sheets.spreadsheet_permission_error"));
    } else {
      toast.error(errorMessage);
    }
  };

  const linkSheet = async () => {
    try {
      if (!isValidGoogleSheetsUrl(spreadsheetUrl)) {
        throw new Error(t("environments.integrations.google_sheets.enter_a_valid_spreadsheet_url_error"));
      }
      if (!selectedSurvey) {
        throw new Error(t("environments.integrations.please_select_a_survey_error"));
      }
      if (selectedElements.length === 0) {
        throw new Error(t("environments.integrations.select_at_least_one_question_error"));
      }
      setIsLinkingSheet(true);
      const spreadsheetId = extractSpreadsheetIdFromUrl(spreadsheetUrl);
      const spreadsheetNameResponse = await getSpreadsheetNameByIdAction({
        googleSheetIntegration,
        environmentId,
        spreadsheetId,
      });

      if (!spreadsheetNameResponse?.data) {
        showErrorMessageToast(spreadsheetNameResponse);
        return;
      }

      const spreadsheetName = spreadsheetNameResponse.data;
      integrationData.spreadsheetId = spreadsheetId;
      integrationData.spreadsheetName = spreadsheetName;
      integrationData.surveyId = selectedSurvey.id;
      integrationData.surveyName = selectedSurvey.name;
      integrationData.elementIds = selectedElements;
      integrationData.elements =
        selectedElements.length === surveyElements.length
          ? t("common.all_questions")
          : t("common.selected_questions");
      integrationData.createdAt = new Date();
      integrationData.includeVariables = includeVariables;
      integrationData.includeHiddenFields = includeHiddenFields;
      integrationData.includeMetadata = includeMetadata;
      integrationData.includeCreatedAt = includeCreatedAt;
      if (selectedIntegration) {
        // update action
        googleSheetIntegrationData.config.data[selectedIntegration.index] = integrationData;
      } else {
        // create action
        googleSheetIntegrationData.config.data.push(integrationData);
      }
      const result = await createOrUpdateIntegrationAction({
        environmentId,
        integrationData: googleSheetIntegrationData,
      });
      if (result?.serverError) {
        toast.error(getFormattedErrorMessage(result));
        return;
      }
      if (selectedIntegration) {
        toast.success(t("environments.integrations.integration_updated_successfully"));
      } else {
        toast.success(t("environments.integrations.integration_added_successfully"));
      }
      resetForm();
      setOpen(false);
    } catch (e) {
      toast.error(e instanceof Error ? e.message : "Unknown error occurred");
    } finally {
      setIsLinkingSheet(false);
    }
  };

  const handleCheckboxChange = (questionId: TSurveyQuestionId) => {
    setSelectedElements((prevValues) =>
      prevValues.includes(questionId)
        ? prevValues.filter((value) => value !== questionId)
        : [...prevValues, questionId]
    );
  };

  const setOpenWithStates = (isOpen: boolean) => {
    resetForm();
    setOpen(isOpen);
  };

  const resetForm = () => {
    setSpreadsheetUrl("");
    setIsLinkingSheet(false);
    setSelectedSurvey(null);
    setIncludeHiddenFields(false);
    setIncludeMetadata(false);
  };

  const deleteLink = async () => {
    googleSheetIntegrationData.config.data.splice(selectedIntegration!.index, 1);
    try {
      setIsDeleting(true);
      const result = await createOrUpdateIntegrationAction({
        environmentId,
        integrationData: googleSheetIntegrationData,
      });
      if (result?.serverError) {
        toast.error(getFormattedErrorMessage(result));
        return;
      }
      toast.success(t("environments.integrations.integration_removed_successfully"));
      setOpen(false);
    } catch (error) {
      toast.error(error instanceof Error ? error.message : "Unknown error occurred");
    } finally {
      setIsDeleting(false);
    }
  };

  return (
    <Dialog open={open} onOpenChange={setOpenWithStates}>
      <DialogContent>
        <DialogHeader>
          <div className="flex items-center space-x-2">
            <div className="relative size-8">
              <Image
                fill
                className="object-contain object-center"
                src={GoogleSheetLogo}
                alt={t("environments.integrations.google_sheets.google_sheet_logo")}
              />
            </div>
            <div className="space-y-0.5">
              <DialogTitle>{t("environments.integrations.google_sheets.link_google_sheet")}</DialogTitle>
              <DialogDescription>
                {t("environments.integrations.google_sheets.google_sheets_integration_description")}
              </DialogDescription>
            </div>
          </div>
        </DialogHeader>
        <form className="space-y-4" onSubmit={handleSubmit(linkSheet)}>
          <DialogBody>
            <div className="w-full space-y-4">
              <div>
                <div className="mb-4">
                  <Label>{t("environments.integrations.google_sheets.spreadsheet_url")}</Label>
                  <Input
                    value={spreadsheetUrl}
                    onChange={(e) => setSpreadsheetUrl(e.target.value)}
                    placeholder="https://docs.google.com/spreadsheets/d/<your-spreadsheet-id>"
                    className="mt-1"
                  />
                </div>
                <div>
                  <DropdownSelector
                    label={t("common.select_survey")}
                    items={surveys}
                    selectedItem={selectedSurvey}
                    setSelectedItem={setSelectedSurvey}
                    disabled={surveys.length === 0}
                  />
                  <p className="m-1 text-xs text-slate-500">
                    {surveys.length === 0 && t("environments.integrations.create_survey_warning")}
                  </p>
                </div>
              </div>
              {selectedSurvey && (
                <div className="space-y-4">
                  <div>
                    <Label htmlFor="Surveys">{t("common.questions")}</Label>
                    <div className="mt-1 max-h-[15vh] overflow-y-auto overflow-x-hidden rounded-lg border border-slate-200">
                      <div className="grid content-center rounded-lg bg-slate-50 p-3 text-left text-sm text-slate-900">
                        {surveyElements.map((question) => (
                          <div key={question.id} className="my-1 flex items-center space-x-2">
                            <label htmlFor={question.id} className="flex cursor-pointer items-center">
                              <Checkbox
                                type="button"
                                id={question.id}
                                value={question.id}
                                className="bg-white"
                                checked={selectedElements.includes(question.id)}
                                onCheckedChange={() => {
                                  handleCheckboxChange(question.id);
                                }}
                              />
                              <span className="ml-2 w-[30rem] truncate">
                                {getTextContent(
                                  recallToHeadline(question.headline, selectedSurvey, false, "default")[
                                    "default"
                                  ]
                                )}
                              </span>
                            </label>
                          </div>
                        ))}
                      </div>
                    </div>
                  </div>
                  <AdditionalIntegrationSettings
                    includeVariables={includeVariables}
                    setIncludeVariables={setIncludeVariables}
                    includeHiddenFields={includeHiddenFields}
                    includeMetadata={includeMetadata}
                    setIncludeHiddenFields={setIncludeHiddenFields}
                    setIncludeMetadata={setIncludeMetadata}
                    includeCreatedAt={includeCreatedAt}
                    setIncludeCreatedAt={setIncludeCreatedAt}
                  />
                </div>
              )}
            </div>
          </DialogBody>
          <DialogFooter>
            {selectedIntegration ? (
              <Button
                type="button"
                variant="destructive"
                loading={isDeleting}
                onClick={() => {
                  deleteLink();
                }}>
                {t("common.delete")}
              </Button>
            ) : (
              <Button
                type="button"
                variant="ghost"
                onClick={() => {
                  setOpen(false);
                  resetForm();
                }}>
                {t("common.cancel")}
              </Button>
            )}
            <Button type="submit" loading={isLinkingSheet}>
              {selectedIntegration
                ? t("common.update")
                : t("environments.integrations.google_sheets.link_google_sheet")}
            </Button>
          </DialogFooter>
        </form>
      </DialogContent>
    </Dialog>
  );
};
