import type { EventStatus } from "@/entities/event";
import { DisplayUser } from "@/features/display-user";
import { apiClient } from "@/shared/api";
import { type Role, checkPermission } from "@/shared/lib/RBAC";
import {
  approveEvent,
  cancelEvent,
  closeEvent,
  declineEvent,
  formatTxError,
} from "@/shared/lib/web3";
import { AcceptDialog } from "@/shared/ui/AcceptDialog";
import { Loader } from "@/shared/ui/Loader";
import { ResultDialog } from "@/shared/ui/ResultDialog";
import { Button } from "@/shared/ui/button";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/shared/ui/dialog";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/shared/ui/select";
import { useMutation, useQuery } from "@tanstack/react-query";
import { useEffect, useState } from "react";
import { Link, useNavigate } from "react-router";
import { useActiveAccount } from "thirdweb/react";
import { useManageEventState } from "../model/slice";

type MaybeManageEventProps = {
  roles: Role[];
  status: EventStatus;
  eventId: number;
  canEdit: boolean;
};

type ManageAction = "decline" | "accept" | "close" | "cancel";

type DistributionProfile = {
  id: number;
  ownerAddress: string;
  recipients: { address: string; share: number }[];
  isActive: boolean;
  createdAt: string;
  updatedAt: string;
};

export const MaybeManageEvent: React.FC<MaybeManageEventProps> = ({
  roles,
  status,
  eventId,
  canEdit,
}) => {
  const [isOpen, setIsOpen] = useState(false);
  const [isProfileDialogOpen, setIsProfileDialogOpen] = useState(false);
  const [selectedProfileId, setSelectedProfileId] = useState<string>("");
  const [modalInfo, setModalInfo] = useState({
    title: "",
    body: "",
    error: false,
  });
  const account = useActiveAccount();
  const { optimisticSetEventStatus, optimisticEventsStatuses } =
    useManageEventState();

  // Fetch distribution profiles owned by the current user
  const { data: profiles, isLoading: isProfilesLoading } = useQuery({
    queryKey: ["distribution-profiles"],
    queryFn: async () => {
      if (!account?.address) return [];
      const resp = await apiClient.GET("/api/distribution-profiles/", {
        headers: { "X-User-Address": account.address },
      });
      if (resp.error || !resp.data) throw new Error("Failed to fetch profiles");
      return resp.data as DistributionProfile[];
    },
    enabled: !!account,
  });

  // Preselect the first profile when profiles are loaded
  useEffect(() => {
    if (profiles && profiles.length > 0 && !selectedProfileId) {
      setSelectedProfileId(String(profiles[0]?.id));
    }
  }, [profiles, selectedProfileId]);

  const { mutate, isPending } = useMutation({
    mutationFn: async (action: ManageAction) => {
      console.log("got manage event action", action);
      console.log("eventId:", eventId, "account:", account?.address);
      if (account == null) throw new Error("Got null account");
      // TODO: Use the same type with EventStatus
      try {
        switch (action) {
          case "accept": {
            console.log("Calling approveEvent with eventId:", eventId);
            const txHash = await approveEvent(
              account,
              BigInt(eventId),
              BigInt(selectedProfileId),
            );
            console.log("approveEvent tx hash:", txHash);
            setModalInfo({
              title: "Event accepting was initiated",
              body: "Event will be accepted soon",
              error: false,
            });
            optimisticSetEventStatus(eventId, "approved");
            break;
          }
          case "decline": {
            console.log("Calling declineEvent with eventId:", eventId);
            const declineTxHash = await declineEvent(account, BigInt(eventId));
            console.log("declineEvent tx hash:", declineTxHash);
            setModalInfo({
              title: "Event declining was inititated",
              body: "Event will be declined soon",
              error: false,
            });
            optimisticSetEventStatus(eventId, "declined");
            break;
          }
          case "close": {
            console.log("Calling closeEvent with eventId:", eventId);
            const closeTxHash = await closeEvent(account, BigInt(eventId));
            console.log("closeEvent tx hash:", closeTxHash);
            setModalInfo({
              title: "Event finishing was initiated",
              body: "Event will be finished soon",
              error: false,
            });
            optimisticSetEventStatus(eventId, "closed");
            break;
          }
          case "cancel": {
            console.log("Calling cancelEvent with eventId:", eventId);
            const cancelTxHash = await cancelEvent(account, BigInt(eventId));
            console.log("cancelEvent tx hash:", cancelTxHash);
            setModalInfo({
              title: "Event cancelling was initiated",
              body: "Event will be cancelled soon",
              error: false,
            });
            optimisticSetEventStatus(eventId, "cancelled");
            break;
          }
          default:
            console.error("Unknown action received:", action);
            setModalInfo({
              title: "Failure",
              body: `Unknown action: ${action}`,
              error: true,
            });
        }
      } catch (e) {
        console.error("Transaction failed with error:", e);
        console.error("Error details:", {
          message: e instanceof Error ? e.message : "Unknown error",
          stack: e instanceof Error ? e.stack : undefined,
          raw: e,
        });

        const errorMessage = formatTxError(e);

        setModalInfo({
          title: "Failure",
          body: errorMessage,
          error: true,
        });
      }
      setIsOpen(true);
    },
    onSuccess: (data) => {
      console.log("Mutation onSuccess callback - data:", data);
    },
    onError: (error) => {
      console.error("Mutation onError callback - error:", error);
      console.error("Error details:", {
        message: error instanceof Error ? error.message : "Unknown error",
        stack: error instanceof Error ? error.stack : undefined,
      });
    },
  });
  const navigate = useNavigate();

  status = optimisticEventsStatuses[eventId] || status;
  const canFinalize = status === "approved";
  const canControl =
    checkPermission(roles, "event:accept/decline") && status === "submitted";

  function onEdit() {
    navigate(`/events/${eventId}/edit`);
  }

  const handleAcceptClick = () => {
    // Open profile selector dialog
    setIsProfileDialogOpen(true);
  };

  const handleProfileConfirm = () => {
    if (!selectedProfileId) {
      setModalInfo({
        title: "Error",
        body: "Please select a distribution profile",
        error: true,
      });
      setIsOpen(true);
      return;
    }
    setIsProfileDialogOpen(false);
    mutate("accept");
  };

  if (status !== "submitted" && !canEdit && !canControl) return;
  if (!account) return <Loader />;

  return (
    <div className="flex flex-col items-center justify-center gap-7 py-10">
      <div className="w-3/4 flex flex-col justify-center gap-3">
        {canEdit && (
          <Button className="w-full" onClick={onEdit} disabled={isPending}>
            Edit
          </Button>
        )}
        {canControl && (
          <div className="flex justify-between gap-3">
            <Button
              className="w-full"
              variant="secondary"
              onClick={handleAcceptClick}
              disabled={isPending}
            >
              Accept
            </Button>
            <AcceptDialog
              title="Are you sure you want to decline the event?"
              option="decline"
              confirmFn={() => mutate("decline")}
              confirmDisabled={isPending}
              confirmText={isPending ? "Sending..." : "Confirm"}
            >
              <Button
                className="w-full"
                variant="destructive"
                disabled={isPending}
              >
                Decline
              </Button>
            </AcceptDialog>
          </div>
        )}
        {canFinalize && (
          <div className="flex justify-between gap-3">
            <AcceptDialog
              title="Are you sure you want to finalize the event?"
              option="accept"
              confirmFn={() => mutate("close")}
              confirmDisabled={isPending}
              confirmText={isPending ? "Sending..." : "Confirm"}
            >
              <Button
                className="w-full"
                variant="secondary"
                disabled={isPending}
              >
                Finalize
              </Button>
            </AcceptDialog>
            <AcceptDialog
              title="Are you sure you want to fuck up the event?"
              option="accept"
              confirmFn={() => mutate("cancel")}
              confirmDisabled={isPending}
              confirmText={isPending ? "Sending..." : "Confirm"}
            >
              <Button
                className="w-full"
                variant="destructive"
                disabled={isPending}
              >
                Fuck up
              </Button>
            </AcceptDialog>
          </div>
        )}
        <ResultDialog
          open={isOpen}
          setOpen={setIsOpen}
          title={modalInfo.title}
          body={modalInfo.body}
          onConfirm={() => {
            setIsOpen(false);
          }}
          failure={modalInfo.error}
        />
      </div>

      {/* Profile Selection Dialog */}
      <Dialog open={isProfileDialogOpen} onOpenChange={setIsProfileDialogOpen}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Select Distribution Profile</DialogTitle>
            <DialogDescription>
              Choose a distribution profile for revenue sharing when approving
              this event.
            </DialogDescription>
          </DialogHeader>
          <div className="py-4">
            {isProfilesLoading ? (
              <div className="flex justify-center py-4">
                <Loader />
              </div>
            ) : profiles && profiles.length > 0 ? (
              <>
                <Select
                  value={selectedProfileId}
                  onValueChange={setSelectedProfileId}
                >
                  <SelectTrigger>
                    <SelectValue placeholder="Select a profile..." />
                  </SelectTrigger>
                  <SelectContent>
                    {profiles.map((profile) => (
                      <SelectItem key={profile.id} value={String(profile.id)}>
                        Profile #{profile.id} ({profile.recipients.length}{" "}
                        recipients)
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>

                {/* Selected Profile Details */}
                {selectedProfileId && (
                  <div className="mt-4 p-4 space-y-3">
                    {(() => {
                      const profile = profiles.find(
                        (p) => String(p.id) === selectedProfileId,
                      );
                      if (!profile) return null;
                      const totalShares = profile.recipients.reduce(
                        (sum, r) => sum + r.share,
                        0,
                      );
                      return (
                        <>
                          <div className="flex justify-between items-center">
                            <span className="text-sm font-semibold">
                              Profile #{profile.id}
                            </span>
                            <span className="text-xs text-muted-foreground">
                              {profile.recipients.length} recipient(s)
                            </span>
                          </div>
                          <div className="text-xs text-muted-foreground flex items-center gap-1">
                            Owner:{" "}
                            <DisplayUser
                              address={profile.ownerAddress || ""}
                              className="text-xs"
                            />
                          </div>

                          {/* Recipients Table */}
                          <div className="mt-3">
                            <table className="w-full text-sm">
                              <thead>
                                <tr>
                                  <th className="text-left py-1 text-xs text-muted-foreground">
                                    Recipient
                                  </th>
                                  <th className="text-right py-1 text-xs text-muted-foreground">
                                    Share
                                  </th>
                                </tr>
                              </thead>
                              <tbody>
                                {profile.recipients?.map((recipient) => (
                                  <tr key={recipient.address}>
                                    <td className="py-2 font-mono text-xs">
                                      {recipient.address?.slice(0, 6)}...
                                      {recipient.address?.slice(-4)}
                                    </td>
                                    <td className="py-2 text-right">
                                      {(recipient.share / 100).toFixed(0)}%
                                    </td>
                                  </tr>
                                ))}
                              </tbody>
                            </table>
                          </div>

                          {/* Platform Fees Info */}
                          <div className="mt-3 pt-3">
                            <div className="text-xs text-muted-foreground">
                              <strong>Platform Fees (Fixed):</strong>
                            </div>
                            <div className="flex justify-between text-xs mt-1">
                              <span>CyberiaDAO:</span>
                              <span>10%</span>
                            </div>
                            <div className="flex justify-between text-xs mt-1">
                              <span>CVE PT PMA:</span>
                              <span>5%</span>
                            </div>
                            <div className="flex justify-between text-sm font-semibold mt-2 pt-1">
                              <span>Your Share:</span>
                              <span>{totalShares / 100}% of 85%</span>
                            </div>
                          </div>
                        </>
                      );
                    })()}
                  </div>
                )}
              </>
            ) : (
              <p className="text-sm text-muted-foreground">
                No distribution profiles found. Please create a profile first.
              </p>
            )}
          </div>
          <DialogFooter className="gap-3">
            <Button
              variant="ghost"
              onClick={() => setIsProfileDialogOpen(false)}
              className="flex-1"
            >
              Cancel
            </Button>
            {profiles && profiles.length > 0 ? (
              <Button
                onClick={handleProfileConfirm}
                disabled={!selectedProfileId || isProfilesLoading}
                className="flex-1"
              >
                Approve
              </Button>
            ) : (
              <Link
                to="/account/distribution-profiles/create"
                onClick={() => setIsProfileDialogOpen(false)}
              >
                <Button>Create One</Button>
              </Link>
            )}
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
};

Graph