"use client";

import { useState, useEffect } from "react";
import { useParticipants, useSetSplits, useTransactionSplits, useBulkAction, useCreateRule, useCurrentUser } from "@/lib/hooks";

interface Split {
  participant_id: number;
  share_percent: number;
}

interface Props {
  transactionId?: number;
  transactionIds?: number[];
  amount?: number;
  description: string;
  merchant?: string;
  onClose: () => void;
}

export function SplitModal({ transactionId, transactionIds, amount, description, merchant, onClose }: Props) {
  const isBulk = !!transactionIds && transactionIds.length > 0;
  const singleId = transactionId ?? 0;

  const { data: participants } = useParticipants();
  const { data: currentUser } = useCurrentUser();
  const { data: existingSplits } = useTransactionSplits(isBulk ? 0 : singleId);
  const setSplits = useSetSplits();
  const bulkAction = useBulkAction();
  const createRule = useCreateRule();

  const [splits, setSplitsState] = useState<Split[]>([]);
  const [error, setError] = useState("");
  const [saveAsRule, setSaveAsRule] = useState(false);
  const [ruleSaved, setRuleSaved] = useState(false);

  // Initialise: bulk always defaults to 100% Me; single loads existing splits
  useEffect(() => {
    if (!participants || participants.length === 0 || !currentUser) return;
    if (isBulk) {
      setSplitsState([{ participant_id: currentUser.id, share_percent: 100 }]);
    } else if (existingSplits && existingSplits.length > 0) {
      setSplitsState(
        existingSplits.map((s: { participant_id: number; share_percent: number }) => ({
          participant_id: s.participant_id,
          share_percent: Number(s.share_percent),
        }))
      );
    } else {
      setSplitsState([{ participant_id: currentUser.id, share_percent: 100 }]);
    }
  }, [existingSplits, participants, isBulk, currentUser]);

  const total = splits.reduce((sum, s) => sum + s.share_percent, 0);

  const toggleParticipant = (id: number) => {
    setSplitsState((prev) => {
      const exists = prev.find((s) => s.participant_id === id);
      if (exists) {
        return prev.filter((s) => s.participant_id !== id);
      }
      // Add with equal split
      const count = prev.length + 1;
      const equal = Math.floor(100 / count);
      const remainder = 100 - equal * count;
      return [
        ...prev.map((s, i) => ({ ...s, share_percent: equal + (i === 0 ? remainder : 0) })),
        { participant_id: id, share_percent: equal },
      ];
    });
  };

  const updateShare = (id: number, value: number) => {
    setSplitsState((prev) =>
      prev.map((s) => (s.participant_id === id ? { ...s, share_percent: value } : s))
    );
  };

  const splitEvenly = () => {
    if (splits.length === 0) return;
    const each = Math.floor(100 / splits.length);
    const remainder = 100 - each * splits.length;
    setSplitsState((prev) =>
      prev.map((s, i) => ({ ...s, share_percent: each + (i === 0 ? remainder : 0) }))
    );
  };

  const isPending = isBulk ? bulkAction.isPending : setSplits.isPending;

  const handleSave = async () => {
    setError("");
    if (Math.abs(total - 100) > 0.01) {
      setError(`Shares must sum to 100% (currently ${total.toFixed(1)}%)`);
      return;
    }
    try {
      if (isBulk) {
        await bulkAction.mutateAsync({ action: "split", ids: transactionIds!, splits });
      } else {
        await setSplits.mutateAsync({ transactionId: singleId, splits });
      }
      if (saveAsRule && !isBulk) {
        const matchValue = merchant || (description.split(" ")[0] ?? description);
        await createRule.mutateAsync({
          name: `Split: ${merchant || description}`,
          conditions: [{ field: "merchant_normalized", operator: "contains", value: matchValue }],
          actions: { apply_split: splits },
          enabled: true,
          priority: 0,
        });
        setRuleSaved(true);
        setTimeout(onClose, 1200);
      } else {
        onClose();
      }
    } catch (e) {
      setError(e instanceof Error ? e.message : "Failed to save splits");
    }
  };

  return (
    <div className="fixed inset-0 bg-black/60 flex items-center justify-center z-50" onClick={onClose}>
      <div
        className="bg-zinc-900 border border-zinc-700 rounded-xl p-6 w-full max-w-md mx-4 shadow-2xl"
        onClick={(e) => e.stopPropagation()}
      >
        <h3 className="text-lg font-semibold mb-1">
          {isBulk ? `Split ${transactionIds!.length} Transactions` : "Split Transaction"}
        </h3>
        <p className="text-sm text-zinc-400 mb-4 truncate">{description}</p>
        {!isBulk && amount !== undefined && (
          <p className="text-2xl font-mono font-semibold mb-6">
            ${Number(amount).toFixed(2)}
          </p>
        )}

        {/* Participant toggles */}
        <div className="space-y-3 mb-4">
          {participants?.map((p) => {
            const split = splits.find((s) => s.participant_id === p.id);
            const active = !!split;
            return (
              <div key={p.id} className="flex items-center gap-3">
                <button
                  onClick={() => toggleParticipant(p.id)}
                  className={`w-8 h-8 rounded-full text-sm font-medium flex-shrink-0 transition-colors ${
                    active
                      ? "bg-blue-600 text-white"
                      : "bg-zinc-800 text-zinc-500 hover:bg-zinc-700"
                  }`}
                >
                  {p.name.charAt(0).toUpperCase()}
                </button>
                <span className="flex-1 text-sm">{p.name}</span>
                {active && (
                  <div className="flex items-center gap-2">
                    <input
                      type="range"
                      min={1}
                      max={99}
                      value={split.share_percent}
                      onChange={(e) => updateShare(p.id, Number(e.target.value))}
                      className="w-24 accent-blue-600"
                    />
                    <span className="w-12 text-right text-sm font-mono">
                      {split.share_percent}%
                    </span>
                    {!isBulk && amount !== undefined && (
                      <span className="w-20 text-right text-sm text-zinc-400 font-mono">
                        ${((amount * split.share_percent) / 100).toFixed(2)}
                      </span>
                    )}
                  </div>
                )}
              </div>
            );
          })}
        </div>

        {/* Total indicator */}
        <div className="flex items-center justify-between mb-4 text-sm">
          <span className={`font-mono ${Math.abs(total - 100) > 0.01 ? "text-red-400" : "text-green-400"}`}>
            Total: {total.toFixed(1)}%
          </span>
          <button
            onClick={splitEvenly}
            className="text-blue-400 hover:text-blue-300 text-xs"
          >
            Split evenly
          </button>
        </div>

        {error && <p className="text-red-400 text-sm mb-3">{error}</p>}

        {ruleSaved && (
          <p className="text-green-400 text-sm mb-3">Rule saved — future matching transactions will be split the same way.</p>
        )}

        {!isBulk && (
          <label className="flex items-center gap-2 text-sm text-zinc-400 mb-3 cursor-pointer select-none">
            <input
              type="checkbox"
              checked={saveAsRule}
              onChange={(e) => setSaveAsRule(e.target.checked)}
              className="accent-blue-500"
            />
            Also save as rule for <span className="text-zinc-200 font-medium">{merchant || description.split(" ")[0]}</span>
          </label>
        )}

        <div className="flex gap-3">
          <button
            onClick={onClose}
            className="flex-1 py-2 bg-zinc-800 hover:bg-zinc-700 rounded-lg text-sm transition-colors"
          >
            Cancel
          </button>
          <button
            onClick={handleSave}
            disabled={isPending || Math.abs(total - 100) > 0.01}
            className="flex-1 py-2 bg-blue-600 hover:bg-blue-700 disabled:opacity-50 rounded-lg text-sm font-medium transition-colors"
          >
            {isPending ? "Saving..." : "Save splits"}
          </button>
        </div>
      </div>
    </div>
  );
}
