"use client";

import { useEffect, useState } from "react";
import {
  Modal,
  ModalBody,
  ModalContent,
  ModalHeader,
  Input,
  Spinner,
} from "@nextui-org/react";
import { FaArrowUpRightFromSquare, FaCheck, FaUsers } from "react-icons/fa6";

import Button from "@/components/common/button";
import { useClientPortalAuth } from "@/components/pages/client/participant-list/common/client-portal-auth-context";
import {
  FieldConfig,
  SessionDetail,
} from "@/types/participant-list/provisional-types";
import {
  getSessionDetailForPortal,
  updateEnrolmentSessionLinkFromPortal,
  updateEnrolmentSessionResearcherFromPortal,
} from "@/services/client/participant-list/portal-actions";
import { useTimezone } from "@/components/pages/client/participant-list/common/timezone-context";
import {
  formatSessionTime,
  formatSlotDate,
  formatSlotDayName,
} from "@/components/pages/client/participant-list/common/format-session-time";
import { isFieldVisible } from "@/components/pages/client/participant-list/common/utils";

type SessionDetailsModalProps = {
  sessionId: string | null;
  canEdit: boolean;
  onClose: () => void;
  visibilityControls: FieldConfig[];
};

type FieldState = {
  draft: string;
  saved: string;
  isSaving: boolean;
  error: string | null;
  justSaved: boolean;
};

const initialField = (value: string | null): FieldState => ({
  draft: value ?? "",
  saved: value ?? "",
  isSaving: false,
  error: null,
  justSaved: false,
});

function SessionDetailsModal({
  sessionId,
  canEdit,
  onClose,
  visibilityControls,
}: SessionDetailsModalProps) {
  const { auth, handlePortalStatus } = useClientPortalAuth();
  const { timezone } = useTimezone();
  const [session, setSession] = useState<SessionDetail | null>(null);
  const [isLoading, setIsLoading] = useState(false);
  const [loadError, setLoadError] = useState<string | null>(null);
  const [link, setLink] = useState<FieldState>(initialField(null));
  const [researcher, setResearcher] = useState<FieldState>(initialField(null));

  useEffect(() => {
    if (!sessionId || !auth) {
      setSession(null);
      return;
    }

    let cancelled = false;
    setIsLoading(true);
    setLoadError(null);

    void (async () => {
      try {
        const result = await getSessionDetailForPortal(auth, sessionId);
        if (cancelled) return;
        if (!result.ok) {
          if (!handlePortalStatus(result.status)) {
            setLoadError("Couldn't load session details. Please try again.");
          }
          return;
        }
        const data = result.data;
        setSession(data);
        setLink(initialField(data.sessionLink ?? null));
        setResearcher(initialField(data.researcher));
      } catch {
        if (!cancelled) {
          setLoadError("Couldn't load session details. Please try again.");
        }
      } finally {
        if (!cancelled) setIsLoading(false);
      }
    })();

    return () => {
      cancelled = true;
    };
  }, [auth, handlePortalStatus, sessionId]);

  const saveLink = async () => {
    if (!session || !auth || !canEdit) return;
    setLink((prev) => ({
      ...prev,
      isSaving: true,
      error: null,
      justSaved: false,
    }));

    const value = link.draft.trim();
    try {
      const result = await updateEnrolmentSessionLinkFromPortal(
        auth,
        session.id,
        value,
      );

      if (result.ok) {
        setLink((prev) => ({
          ...prev,
          saved: value,
          draft: value,
          justSaved: true,
        }));
      } else if (!handlePortalStatus(result.status)) {
        setLink((prev) => ({
          ...prev,
          error:
            "Something went wrong saving the session link. Please try again.",
        }));
      }
    } catch {
      setLink((prev) => ({
        ...prev,
        error:
          "Something went wrong saving the session link. Please try again.",
      }));
    } finally {
      setLink((prev) => ({ ...prev, isSaving: false }));
    }
  };

  const saveResearcher = async () => {
    if (!session || !auth || !canEdit) return;
    setResearcher((prev) => ({
      ...prev,
      isSaving: true,
      error: null,
      justSaved: false,
    }));

    const value = researcher.draft.trim();
    try {
      const result = await updateEnrolmentSessionResearcherFromPortal(
        auth,
        session.id,
        value,
      );

      if (result.ok) {
        setResearcher((prev) => ({
          ...prev,
          saved: value,
          draft: value,
          justSaved: true,
        }));
      } else if (!handlePortalStatus(result.status)) {
        setResearcher((prev) => ({
          ...prev,
          error:
            "Something went wrong saving the researcher. Please try again.",
        }));
      }
    } catch {
      setResearcher((prev) => ({
        ...prev,
        error: "Something went wrong saving the researcher. Please try again.",
      }));
    } finally {
      setResearcher((prev) => ({ ...prev, isSaving: false }));
    }
  };

  const linkChanged = link.draft.trim() !== link.saved.trim();
  const researcherChanged = researcher.draft.trim() !== researcher.saved.trim();

  return (
    <Modal isOpen={sessionId !== null} size="2xl" onClose={onClose}>
      <ModalContent>
        <ModalHeader className="flex flex-col gap-1">
          <h3 className="font-inter text-lg font-black text-gray-900 dark:text-white">
            Session details
          </h3>
          {session && (
            <p className="text-xs text-gray-500 dark:text-neutral-400">
              {formatSlotDayName(session.startTime, timezone)}{" "}
              {formatSlotDate(session.startTime, timezone)} ·{" "}
              {formatSessionTime(session.startTime, timezone)} –{" "}
              {formatSessionTime(session.endTime, timezone)}
            </p>
          )}
        </ModalHeader>
        <ModalBody className="pb-6">
          {isLoading && (
            <div className="flex justify-center py-8">
              <Spinner />
            </div>
          )}
          {loadError && (
            <p className="text-sm text-red-600 dark:text-red-400">
              {loadError}
            </p>
          )}
          {session && !isLoading && (
            <div className="flex flex-col gap-5">
              <div className="grid grid-cols-2 gap-3 text-sm">
                <div className="rounded-lg bg-gray-100 p-3 dark:bg-neutral-800">
                  <p className="text-[10px] font-semibold uppercase tracking-widest text-gray-400 dark:text-gray-300">
                    Capacity
                  </p>
                  <p className="mt-1 flex items-center gap-1.5 font-semibold text-gray-900 dark:text-white">
                    <FaUsers className="size-3" />
                    {session.filled}/{session.capacity}
                    {session.filled >= session.capacity ? " · Full" : ""}
                  </p>
                </div>
                {session.location &&
                  isFieldVisible("location", visibilityControls) && (
                    <div className="rounded-lg bg-gray-100 p-3 dark:bg-neutral-800">
                      <p className="text-[10px] font-semibold uppercase tracking-widest text-gray-400 dark:text-gray-300">
                        Location
                      </p>
                      <p className="mt-1 font-semibold text-gray-900 dark:text-white">
                        {session.location}
                      </p>
                    </div>
                  )}
              </div>

              <div className="space-y-2">
                <p className="text-xs font-semibold text-gray-500 dark:text-neutral-400">
                  Researcher
                </p>
                {!canEdit ? (
                  <p className="text-sm text-gray-900 dark:text-white">
                    {researcher.saved || "Not set."}
                  </p>
                ) : (
                  <>
                    <div className="flex items-end gap-2">
                      <Input
                        className="flex-1"
                        isDisabled={researcher.isSaving}
                        placeholder="e.g. Dr. Jane Doe"
                        value={researcher.draft}
                        onChange={(e) =>
                          setResearcher((prev) => ({
                            ...prev,
                            draft: e.target.value,
                            justSaved: false,
                          }))
                        }
                      />
                      <Button
                        btnLabel="Save"
                        customVariant="client"
                        isDisabled={!researcherChanged || researcher.isSaving}
                        isLoading={researcher.isSaving}
                        size="md"
                        onClick={saveResearcher}
                      />
                    </div>
                    {researcher.justSaved && !researcher.error && (
                      <p className="flex items-center gap-1.5 text-xs text-emerald-600 dark:text-emerald-400">
                        <FaCheck className="size-2.5" />
                        Researcher saved.
                      </p>
                    )}
                    {researcher.error && (
                      <p className="text-xs text-red-600 dark:text-red-400">
                        {researcher.error}
                      </p>
                    )}
                  </>
                )}
              </div>

              {isFieldVisible("sessionLink", visibilityControls) && (
                <div className="space-y-2">
                  <p className="text-xs font-semibold text-gray-500 dark:text-neutral-400">
                    Session link
                  </p>
                  {!canEdit ? (
                    link.saved ? (
                      <div className="flex items-center justify-between gap-2">
                        <p className="break-all text-sm text-gray-900 dark:text-white">
                          {link.saved}
                        </p>
                        <Button
                          btnLabel="Join"
                          customVariant="client"
                          href={link.saved}
                          rel="noopener noreferrer"
                          size="sm"
                          startContent={
                            <FaArrowUpRightFromSquare className="size-3" />
                          }
                          target="_blank"
                        />
                      </div>
                    ) : (
                      <p className="text-sm text-gray-500 dark:text-neutral-400">
                        No session link has been added yet.
                      </p>
                    )
                  ) : (
                    <>
                      <div className="flex items-end gap-2">
                        <Input
                          className="flex-1"
                          isDisabled={link.isSaving}
                          placeholder="https://..."
                          value={link.draft}
                          onChange={(e) =>
                            setLink((prev) => ({
                              ...prev,
                              draft: e.target.value,
                              justSaved: false,
                            }))
                          }
                        />
                        <Button
                          btnLabel="Save"
                          customVariant="client"
                          isDisabled={!linkChanged || link.isSaving}
                          isLoading={link.isSaving}
                          size="md"
                          onClick={saveLink}
                        />
                        {link.saved && (
                          <Button
                            btnLabel="Join"
                            customVariant="client"
                            href={link.saved}
                            rel="noopener noreferrer"
                            size="md"
                            startContent={
                              <FaArrowUpRightFromSquare className="size-3" />
                            }
                            target="_blank"
                          />
                        )}
                      </div>
                      {link.justSaved && !link.error && (
                        <p className="flex items-center gap-1.5 text-xs text-emerald-600 dark:text-emerald-400">
                          <FaCheck className="size-2.5" />
                          Session link saved.
                        </p>
                      )}
                      {link.error && (
                        <p className="text-xs text-red-600 dark:text-red-400">
                          {link.error}
                        </p>
                      )}
                    </>
                  )}
                </div>
              )}
            </div>
          )}
        </ModalBody>
      </ModalContent>
    </Modal>
  );
}

export default SessionDetailsModal;
