"use client";

import { useEffect, useRef, useState, useCallback, useLayoutEffect } from "react";
import { createPortal } from "react-dom";
import type { WorkflowDocument, OcrBank } from "@/types/ocr";
import { FileText, Eye, CheckCircle, XCircle, Zap, Search, Plus, ChevronDown } from "lucide-react";

interface BankSelectProps {
  banks: OcrBank[];
  value: string;
  onChange: (bankId: string) => void;
  onCreateBank: () => void;
}

function computeDropdownPosition(buttonEl: HTMLElement): React.CSSProperties {
  const rect = buttonEl.getBoundingClientRect();
  const spaceBelow = window.innerHeight - rect.bottom;
  const openUpward = spaceBelow < 280;

  return {
    position: "fixed" as const,
    width: rect.width,
    left: rect.left,
    ...(openUpward
      ? { bottom: window.innerHeight - rect.top + 4 }
      : { top: rect.bottom + 4 }),
    zIndex: 9999,
  };
}

function BankSelect({ banks, value, onChange, onCreateBank }: BankSelectProps) {
  const [open, setOpen] = useState(false);
  const [search, setSearch] = useState("");
  const [dropdownStyle, setDropdownStyle] = useState<React.CSSProperties>({});
  const buttonRef = useRef<HTMLButtonElement>(null);
  const dropdownRef = useRef<HTMLDivElement>(null);
  const inputRef = useRef<HTMLInputElement>(null);
  const [mounted, setMounted] = useState(false);

  useEffect(() => { setMounted(true); }, []);

  const selectedBank = banks.find((b) => String(b.bank_id) === String(value));

  const filtered = search.trim()
    ? banks.filter((b) =>
        b.bank_name.toLowerCase().includes(search.toLowerCase())
      )
    : banks;

  const closeDropdown = useCallback(() => {
    setOpen(false);
    setSearch("");
  }, []);

  const toggleOpen = useCallback(() => {
    setOpen((prev) => {
      if (!prev && buttonRef.current) {
        // Calculate position synchronously on open
        setDropdownStyle(computeDropdownPosition(buttonRef.current));
      }
      return !prev;
    });
  }, []);

  // Recalculate position on layout if open (catches any initial mismatch)
  useLayoutEffect(() => {
    if (open && buttonRef.current) {
      setDropdownStyle(computeDropdownPosition(buttonRef.current));
      setTimeout(() => inputRef.current?.focus(), 0);
    }
  }, [open]);

  // Close on click outside
  useEffect(() => {
    if (!open) return;
    function handleClickOutside(e: MouseEvent) {
      const target = e.target as Node;
      if (
        buttonRef.current?.contains(target) ||
        dropdownRef.current?.contains(target)
      ) {
        return;
      }
      closeDropdown();
    }
    document.addEventListener("mousedown", handleClickOutside);
    return () => document.removeEventListener("mousedown", handleClickOutside);
  }, [open, closeDropdown]);

  // Close on scroll/resize
  useEffect(() => {
    if (!open) return;
    const handleClose = () => closeDropdown();
    window.addEventListener("scroll", handleClose, true);
    window.addEventListener("resize", handleClose);
    return () => {
      window.removeEventListener("scroll", handleClose, true);
      window.removeEventListener("resize", handleClose);
    };
  }, [open, closeDropdown]);

  const dropdownContent =
    open && mounted
      ? createPortal(
          <div
            ref={dropdownRef}
            style={dropdownStyle}
            className="bg-white border border-gray-200 rounded-lg shadow-xl"
          >
            {/* Add Bank button at top */}
            <button
              type="button"
              onClick={() => {
                onCreateBank();
                closeDropdown();
              }}
              className="w-full flex items-center gap-2 px-3 py-2 text-xs font-medium text-[#428B4D] hover:bg-[#428B4D]/5 border-b border-gray-100 transition-colors rounded-t-lg"
            >
              <Plus className="h-3.5 w-3.5" />
              Add New Bank
            </button>

            {/* Search input */}
            <div className="p-2 border-b border-gray-100">
              <div className="relative">
                <Search className="absolute left-2.5 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-gray-400" />
                <input
                  ref={inputRef}
                  type="text"
                  value={search}
                  onChange={(e) => setSearch(e.target.value)}
                  placeholder="Search banks..."
                  className="w-full pl-8 pr-3 py-1.5 text-xs border border-gray-200 rounded-md bg-gray-50 focus:outline-none focus:ring-1 focus:ring-[#428B4D]/30 focus:border-[#428B4D]/50 focus:bg-white transition-colors"
                />
              </div>
            </div>

            {/* Bank options */}
            <div
              className="max-h-48 overflow-y-auto rounded-b-lg"
              style={{ scrollbarWidth: "thin", scrollbarColor: "#d1d5db transparent" }}
            >
              {filtered.length === 0 ? (
                <div className="px-3 py-3 text-xs text-gray-400 text-center">
                  No banks found
                </div>
              ) : (
                filtered.map((bank) => (
                  <button
                    key={bank.bank_id}
                    type="button"
                    onClick={() => {
                      onChange(String(bank.bank_id));
                      closeDropdown();
                    }}
                    className={`w-full text-left px-3 py-2 text-xs hover:bg-gray-50 transition-colors ${
                      String(bank.bank_id) === String(value)
                        ? "bg-[#428B4D]/5 text-[#428B4D] font-medium"
                        : "text-gray-700"
                    }`}
                  >
                    {bank.bank_name}
                    {bank.account_number && (
                      <span className="ml-1 text-gray-400">
                        ({bank.account_number})
                      </span>
                    )}
                  </button>
                ))
              )}
            </div>
          </div>,
          document.body
        )
      : null;

  return (
    <div className="flex-1 max-w-xs">
      <button
        ref={buttonRef}
        type="button"
        onClick={toggleOpen}
        className="w-full flex items-center justify-between gap-2 px-3 py-1.5 border border-gray-200/80 rounded-lg text-xs bg-white hover:border-gray-300 focus:outline-none focus:ring-2 focus:ring-[#428B4D]/30 focus:border-[#428B4D]/50 transition-shadow"
      >
        <span className={selectedBank ? "text-gray-800" : "text-gray-400"}>
          {selectedBank ? selectedBank.bank_name : "-- Select Bank --"}
        </span>
        <ChevronDown
          className={`h-3.5 w-3.5 text-gray-400 transition-transform ${open ? "rotate-180" : ""}`}
        />
      </button>
      {dropdownContent}
    </div>
  );
}

interface WorkflowDocumentsListProps {
  documents: WorkflowDocument[];
  banks: OcrBank[];
  onAssignBank: (documentId: string, bankId: string) => void;
  onCreateBank: (docId: string) => void;
  onReviewPositions: (index: number) => void;
}

export function WorkflowDocumentsList({
  documents,
  banks,
  onAssignBank,
  onCreateBank,
  onReviewPositions,
}: WorkflowDocumentsListProps) {
  const [listMounted, setListMounted] = useState(false);

  useEffect(() => {
    const timer = setTimeout(() => setListMounted(true), 50);
    return () => clearTimeout(timer);
  }, []);

  if (documents.length === 0) return null;

  return (
    <div className="space-y-4">
      <h3 className="text-sm font-semibold text-gray-700">
        Processed Documents ({documents.length})
      </h3>

      <div className="space-y-3">
        {documents.map((doc, index) => {
          const bondCount = doc.extracted_data?.bondPositions?.length || 0;
          const equityCount = doc.extracted_data?.equityPositions?.length || 0;
          const cashCount = doc.extracted_data?.cashPositions?.length || 0;
          const totalPositions = bondCount + equityCount + cashCount;
          const isError = doc.status === "error";

          return (
            <div
              key={doc.document_id}
              className={`border rounded-xl p-4 bg-white transition-all duration-500 ease-out hover:shadow-md ${
                isError
                  ? "border-red-200 hover:border-red-300"
                  : "border-gray-200/80 hover:border-[#428B4D]/30"
              }`}
              style={{
                opacity: listMounted ? 1 : 0,
                transform: listMounted ? "translateY(0)" : "translateY(10px)",
                transitionDelay: `${index * 80}ms`,
              }}
            >
              <div className="flex items-start justify-between">
                <div className="flex items-start gap-3">
                  <div
                    className={`flex h-9 w-9 items-center justify-center rounded-lg mt-0.5 transition-colors ${
                      isError ? "bg-red-50" : "bg-[#428B4D]/10"
                    }`}
                  >
                    <FileText
                      className={`h-4.5 w-4.5 ${
                        isError ? "text-red-400" : "text-[#428B4D]"
                      }`}
                    />
                  </div>
                  <div>
                    <div className="flex items-center gap-2 flex-wrap">
                      <span className="text-sm font-medium text-gray-800">
                        {doc.filename}
                      </span>
                      {doc.autoAssigned && (
                        <span className="inline-flex items-center gap-0.5 px-2 py-0.5 rounded-full text-[10px] font-semibold bg-[#428B4D]/10 text-[#428B4D]">
                          <Zap className="h-2.5 w-2.5" />
                          Auto-assigned
                        </span>
                      )}
                    </div>

                    <div className="flex items-center gap-3 mt-1.5 flex-wrap">
                      {isError ? (
                        <span className="inline-flex items-center gap-1 text-[10px] text-red-600 font-medium">
                          <XCircle className="h-3 w-3" />
                          Processing failed
                        </span>
                      ) : (
                        <>
                          <span className="inline-flex items-center gap-1 text-[10px] text-[#428B4D] font-medium">
                            <CheckCircle className="h-3 w-3" />
                            Processed
                          </span>
                          <span className="text-[10px] text-gray-400">
                            {totalPositions} positions ({bondCount} bonds,{" "}
                            {equityCount} equities, {cashCount} cash)
                          </span>
                        </>
                      )}
                    </div>
                  </div>
                </div>

                {!isError && (
                  <button
                    onClick={() => onReviewPositions(index)}
                    className="inline-flex items-center gap-1.5 px-3 py-1.5 text-[11px] font-medium border border-gray-200/80 rounded-lg hover:bg-[#428B4D]/5 hover:border-[#428B4D]/30 hover:text-[#428B4D] text-gray-600 transition-all duration-200 active:scale-[0.97]"
                  >
                    <Eye className="h-3.5 w-3.5" />
                    Review
                  </button>
                )}
              </div>

              {/* Bank assignment */}
              {!isError && (
                <div className="mt-3 flex items-center gap-2.5 pl-12">
                  <label className="text-xs text-gray-500 font-medium">
                    Bank:
                  </label>
                  <BankSelect
                    banks={banks}
                    value={doc.bank_id || ""}
                    onChange={(bankId) =>
                      onAssignBank(doc.document_id, bankId)
                    }
                    onCreateBank={() => onCreateBank(doc.document_id)}
                  />
                </div>
              )}
            </div>
          );
        })}
      </div>
    </div>
  );
}
