"use client";

import { useState } from "react";
import { IntegerInput } from "@scaffold-ui/debug-contracts";
import { parseEther } from "viem";
import { usePublicClient } from "wagmi";
import TooltipInfo from "~~/components/TooltipInfo";
import { useScaffoldWriteContract } from "~~/hooks/scaffold-eth";
import { useChallengeState } from "~~/services/store/challengeStore";
import { getRandomQuestion } from "~~/utils/helpers";
import { notification } from "~~/utils/scaffold-eth";

const MINIMUM_ASSERTION_WINDOW = 3;

const getStartTimestamp = (timestamp: bigint, startInMinutes: string) => {
  if (startInMinutes.length === 0) return 0n;
  if (Number(startInMinutes) === 0) return 0n;
  return timestamp + BigInt(startInMinutes) * 60n;
};

const getEndTimestamp = (timestamp: bigint, startTimestamp: bigint, durationInMinutes: string) => {
  if (durationInMinutes.length === 0) return 0n;
  if (Number(durationInMinutes) === MINIMUM_ASSERTION_WINDOW) return 0n;
  if (startTimestamp === 0n) return timestamp + BigInt(durationInMinutes) * 60n;
  return startTimestamp + BigInt(durationInMinutes) * 60n;
};

interface SubmitAssertionModalProps {
  isOpen: boolean;
  onClose: () => void;
}

const SubmitAssertionModal = ({ isOpen, onClose }: SubmitAssertionModalProps) => {
  const { timestamp } = useChallengeState();
  const [isLoading, setIsLoading] = useState(false);
  const publicClient = usePublicClient();

  const [description, setDescription] = useState("");
  const [reward, setReward] = useState<string>("");
  const [startInMinutes, setStartInMinutes] = useState<string>("");
  const [durationInMinutes, setDurationInMinutes] = useState<string>("");

  const { writeContractAsync } = useScaffoldWriteContract({ contractName: "OptimisticOracle" });

  const handleRandomQuestion = () => {
    setDescription(getRandomQuestion());
  };

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    if (durationInMinutes.length > 0 && Number(durationInMinutes) < MINIMUM_ASSERTION_WINDOW) {
      notification.error(
        `Duration must be at least ${MINIMUM_ASSERTION_WINDOW} minutes or leave blank to use default value`,
      );
      return;
    }

    if (Number(reward) === 0) {
      notification.error(`Reward must be greater than 0 ETH`);
      return;
    }

    if (!publicClient) {
      notification.error("Public client not found");
      return;
    }

    try {
      setIsLoading(true);
      let recentTimestamp = timestamp;
      if (!recentTimestamp) {
        const block = await publicClient.getBlock();
        recentTimestamp = block.timestamp;
      }

      const startTimestamp = getStartTimestamp(recentTimestamp, startInMinutes);
      const endTimestamp = getEndTimestamp(recentTimestamp, startTimestamp, durationInMinutes);

      await writeContractAsync({
        functionName: "assertEvent",
        args: [description.trim(), startTimestamp, endTimestamp],
        value: parseEther(reward),
      });
      // Reset form after successful submission
      setDescription("");
      setReward("");
      setStartInMinutes("");
      setDurationInMinutes("");
      onClose();
    } catch (error) {
      console.log("Error with submission", error);
    } finally {
      setIsLoading(false);
    }
  };

  const handleClose = () => {
    onClose();
    // Reset form when closing
    setDescription("");
    setReward("");
    setStartInMinutes("");
    setDurationInMinutes("");
  };

  if (!isOpen) return null;
  const readyToSubmit = description.trim().length > 0 && reward.trim().length > 0;

  return (
    <>
      <input type="checkbox" id="assertion-modal" className="modal-toggle" checked={isOpen} readOnly />
      <label htmlFor="assertion-modal" className="modal cursor-pointer" onClick={handleClose}>
        <label className="modal-box relative max-w-md w-full bg-base-100" htmlFor="" onClick={e => e.stopPropagation()}>
          {/* dummy input to capture event onclick on modal box */}
          <input className="h-0 w-0 absolute top-0 left-0" />

          {/* Close button */}
          <button onClick={handleClose} className="btn btn-ghost btn-sm btn-circle absolute right-3 top-3">
            ✕
          </button>

          <div className="relative">
            <TooltipInfo
              top={-2}
              right={5}
              className="tooltip-left"
              infoText="Create a new assertion with your reward stake. Leave time inputs blank to use default values."
            />
          </div>

          {/* Modal Content */}
          <div>
            {/* Header */}
            <div className="text-center mb-6">
              <h2 className="text-xl font-bold">Submit New Assertion</h2>
            </div>

            {/* Form */}
            <form onSubmit={handleSubmit} className="space-y-4">
              {/* Description Input */}
              <div>
                <label className="label">
                  <span className="text-accent font-medium">
                    Description <span className="text-red-500">*</span>
                  </span>
                </label>
                <div className="flex gap-2 items-start">
                  <div className="flex-1">
                    <div className="flex border-2 border-base-300 bg-base-200 rounded-full text-accent">
                      <textarea
                        name="description"
                        value={description}
                        onChange={e => setDescription(e.target.value)}
                        placeholder="Enter assertion description..."
                        className="input input-ghost focus-within:border-transparent leading-8 focus:outline-hidden focus:bg-transparent h-auto min-h-[2.2rem] px-4 border w-full font-medium placeholder:text-accent/70 text-base-content/70 focus:text-base-content/70 whitespace-pre-wrap overflow-x-hidden"
                        rows={2}
                      />
                    </div>
                  </div>
                  <button
                    type="button"
                    onClick={handleRandomQuestion}
                    className="btn btn-secondary btn-sm"
                    title="Select random question"
                  >
                    🎲
                  </button>
                </div>
              </div>
              <div>
                <label className="label">
                  <span className="text-accent font-medium">
                    Reward (ETH) <span className="text-red-500">*</span>
                  </span>
                </label>
                <IntegerInput
                  name="reward"
                  placeholder={`0.01`}
                  value={reward}
                  onChange={newValue => setReward(newValue)}
                  disableMultiplyBy1e18
                />
              </div>
              {/* Start Time and End Time Inputs */}
              <div className="grid grid-cols-2 gap-4">
                <div>
                  <label className="label">
                    <span className="text-accent font-medium">Start in (minutes)</span>
                  </label>
                  <IntegerInput
                    name="startTime"
                    placeholder="blank = now"
                    value={startInMinutes}
                    onChange={newValue => setStartInMinutes(newValue)}
                    disableMultiplyBy1e18
                  />
                </div>
                <div>
                  <label className="label">
                    <span className="text-accent font-medium">Duration (minutes)</span>
                  </label>
                  <IntegerInput
                    name="endTime"
                    placeholder={`minimum ${MINIMUM_ASSERTION_WINDOW} minutes`}
                    value={durationInMinutes}
                    onChange={newValue => setDurationInMinutes(newValue)}
                    disableMultiplyBy1e18
                  />
                </div>
              </div>
              {/* Action Buttons */}
              <div className="flex gap-3 mt-6">
                <button type="submit" className="btn btn-primary flex-1" disabled={isLoading || !readyToSubmit}>
                  {isLoading && <span className="loading loading-spinner loading-xs"></span>}
                  Submit
                </button>
              </div>
            </form>
          </div>
        </label>
      </label>
    </>
  );
};

export const SubmitAssertionButton = () => {
  const [isModalOpen, setIsModalOpen] = useState(false);

  const openModal = () => setIsModalOpen(true);
  const closeModal = () => setIsModalOpen(false);

  return (
    <>
      {/* Button */}
      <div className="my-8 flex justify-center">
        <button className="btn btn-primary btn-lg" onClick={openModal}>
          Submit New Assertion
        </button>
      </div>

      {/* Modal - only mounted when open */}
      {isModalOpen && <SubmitAssertionModal isOpen={isModalOpen} onClose={closeModal} />}
    </>
  );
};
