"use client";

import { useState } from "react";
import type { DashboardHoldingItem } from "@/features/dashboard/types/dashboard.types";
import { Loader2 } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { useOrder } from "@/features/trade/hooks/useOrder";
import { useKisRuntimeStore } from "@/features/settings/store/use-kis-runtime-store";
import type {
  DashboardOrderSide,
  DashboardStockItem,
} from "@/features/trade/types/trade.types";
import { parseKisAccountParts } from "@/lib/kis/account";
import { cn } from "@/lib/utils";

interface OrderFormProps {
  stock?: DashboardStockItem;
  matchedHolding?: DashboardHoldingItem | null;
}

/**
 * @description 대시보드 주문 패널에서 매수/매도 주문을 입력하고 전송합니다.
 * @see features/trade/hooks/useOrder.ts - placeOrder 주문 API 호출
 * @see features/trade/components/layout/TradeDashboardContent.tsx - orderForm prop으로 DashboardLayout에 전달
 */
export function OrderForm({ stock, matchedHolding }: OrderFormProps) {
  const verifiedCredentials = useKisRuntimeStore(
    (state) => state.verifiedCredentials,
  );
  const { placeOrder, isLoading, error } = useOrder();

  // ========== FORM STATE ==========
  const [price, setPrice] = useState<string>(
    stock?.currentPrice.toString() || "",
  );
  const [quantity, setQuantity] = useState<string>("");
  const [activeTab, setActiveTab] = useState<"buy" | "sell">("buy");

  // ========== ORDER HANDLER ==========
  /**
   * UI 흐름: 매수하기/매도하기 버튼 클릭 -> handleOrder -> placeOrder API 호출 -> 주문번호 반환 -> alert
   */
  const handleOrder = async (side: DashboardOrderSide) => {
    if (!stock || !verifiedCredentials) return;

    const priceNum = parseInt(price.replace(/,/g, ""), 10);
    const qtyNum = parseInt(quantity.replace(/,/g, ""), 10);

    if (Number.isNaN(priceNum) || priceNum <= 0) {
      alert("가격을 올바르게 입력해 주세요.");
      return;
    }
    if (Number.isNaN(qtyNum) || qtyNum <= 0) {
      alert("수량을 올바르게 입력해 주세요.");
      return;
    }
    if (!verifiedCredentials.accountNo) {
      alert("계좌번호가 없습니다. 설정에서 계좌번호를 입력해 주세요.");
      return;
    }

    const accountParts = parseKisAccountParts(verifiedCredentials.accountNo);
    if (!accountParts) {
      alert(
        "계좌번호 형식이 올바르지 않습니다. 설정에서 8-2 형식(예: 12345678-01)으로 다시 확인해 주세요.",
      );
      return;
    }

    const response = await placeOrder(
      {
        symbol: stock.symbol,
        side,
        orderType: "limit",
        price: priceNum,
        quantity: qtyNum,
        accountNo: `${accountParts.accountNo}-${accountParts.accountProductCode}`,
        accountProductCode: accountParts.accountProductCode,
      },
      verifiedCredentials,
    );

    if (response?.orderNo) {
      alert(`주문 전송 완료: ${response.orderNo}`);
      setQuantity("");
    }
  };

  const totalPrice =
    parseInt(price.replace(/,/g, "") || "0", 10) *
    parseInt(quantity.replace(/,/g, "") || "0", 10);

  const setPercent = (pct: string) => {
    const ratio = Number.parseInt(pct.replace("%", ""), 10) / 100;
    if (!Number.isFinite(ratio) || ratio <= 0) return;

    // UI 흐름: 비율 버튼 클릭 -> 보유수량 기준 계산(매도 탭) -> 주문수량 입력값 반영
    if (activeTab === "sell" && matchedHolding?.quantity) {
      const calculatedQuantity = Math.max(
        1,
        Math.floor(matchedHolding.quantity * ratio),
      );
      setQuantity(String(calculatedQuantity));
    }
  };

  const isMarketDataAvailable = Boolean(stock);
  const isBuy = activeTab === "buy";

  return (
    <div className="h-full bg-background p-3 dark:bg-brand-950/55 sm:p-4">
      <Tabs
        value={activeTab}
        onValueChange={(value) => setActiveTab(value as "buy" | "sell")}
        className="flex h-full w-full flex-col"
      >
        {/* ========== ORDER SIDE TABS ========== */}
        <TabsList className="mb-3 grid h-10 w-full grid-cols-2 gap-0.5 rounded-lg border border-border/60 bg-muted/30 p-0.5 dark:border-brand-700/50 dark:bg-brand-900/25 sm:mb-4">
          <TabsTrigger
            value="buy"
            className={cn(
              "!h-full rounded-md border border-transparent text-sm font-semibold text-foreground/70 transition-all dark:text-brand-100/70",
              "data-[state=active]:border-red-400/50 data-[state=active]:bg-red-600 data-[state=active]:text-white data-[state=active]:shadow-[0_2px_8px_rgba(220,38,38,0.4)]",
            )}
          >
            매수
          </TabsTrigger>
          <TabsTrigger
            value="sell"
            className={cn(
              "!h-full rounded-md border border-transparent text-sm font-semibold text-foreground/70 transition-all dark:text-brand-100/70",
              "data-[state=active]:border-blue-400/50 data-[state=active]:bg-blue-600 data-[state=active]:text-white data-[state=active]:shadow-[0_2px_8px_rgba(37,99,235,0.4)]",
            )}
          >
            매도
          </TabsTrigger>
        </TabsList>

        {/* ========== CURRENT PRICE INFO ========== */}
        {stock && (
          <div
            className={cn(
              "mb-3 flex items-center justify-between rounded-md border px-3 py-2 text-xs",
              isBuy
                ? "border-red-200/60 bg-red-50/50 dark:border-red-800/35 dark:bg-red-950/25"
                : "border-blue-200/60 bg-blue-50/50 dark:border-blue-800/35 dark:bg-blue-950/25",
            )}
          >
            <span className="text-muted-foreground dark:text-brand-100/65">
              현재가
            </span>
            <span
              className={cn(
                "font-bold tabular-nums",
                isBuy
                  ? "text-red-600 dark:text-red-400"
                  : "text-blue-600 dark:text-blue-400",
              )}
            >
              {stock.currentPrice.toLocaleString()}원
            </span>
          </div>
        )}

        {/* ========== BUY TAB ========== */}
        <TabsContent
          value="buy"
          className="flex flex-1 flex-col space-y-2.5 data-[state=inactive]:hidden sm:space-y-3"
        >
          <OrderInputs
            type="buy"
            price={price}
            setPrice={setPrice}
            quantity={quantity}
            setQuantity={setQuantity}
            totalPrice={totalPrice}
            disabled={!isMarketDataAvailable}
            hasError={Boolean(error)}
            errorMessage={error}
          />
          <PercentButtons onSelect={setPercent} />
          <div className="mt-auto space-y-2.5 sm:space-y-3">
            <HoldingInfoPanel holding={matchedHolding} />
            <Button
              className="h-11 w-full rounded-lg bg-red-600 text-base font-bold text-white shadow-[0_4px_14px_rgba(220,38,38,0.4)] ring-1 ring-red-300/30 transition-all hover:bg-red-700 hover:shadow-[0_4px_20px_rgba(220,38,38,0.5)] dark:bg-red-500 dark:ring-red-300/40 dark:hover:bg-red-400 sm:h-12 sm:text-lg"
              disabled={isLoading || !isMarketDataAvailable}
              onClick={() => handleOrder("buy")}
            >
              {isLoading ? (
                <Loader2 className="mr-2 animate-spin" />
              ) : (
                "매수하기"
              )}
            </Button>
          </div>
        </TabsContent>

        {/* ========== SELL TAB ========== */}
        <TabsContent
          value="sell"
          className="flex flex-1 flex-col space-y-2.5 data-[state=inactive]:hidden sm:space-y-3"
        >
          <OrderInputs
            type="sell"
            price={price}
            setPrice={setPrice}
            quantity={quantity}
            setQuantity={setQuantity}
            totalPrice={totalPrice}
            disabled={!isMarketDataAvailable}
            hasError={Boolean(error)}
            errorMessage={error}
          />
          <PercentButtons onSelect={setPercent} />
          <div className="mt-auto space-y-2.5 sm:space-y-3">
            <HoldingInfoPanel holding={matchedHolding} />
            <Button
              className="h-11 w-full rounded-lg bg-blue-600 text-base font-bold text-white shadow-[0_4px_14px_rgba(37,99,235,0.4)] ring-1 ring-blue-300/30 transition-all hover:bg-blue-700 hover:shadow-[0_4px_20px_rgba(37,99,235,0.5)] dark:bg-blue-500 dark:ring-blue-300/40 dark:hover:bg-blue-400 sm:h-12 sm:text-lg"
              disabled={isLoading || !isMarketDataAvailable}
              onClick={() => handleOrder("sell")}
            >
              {isLoading ? (
                <Loader2 className="mr-2 animate-spin" />
              ) : (
                "매도하기"
              )}
            </Button>
          </div>
        </TabsContent>
      </Tabs>
    </div>
  );
}

/**
 * @description 주문 입력 영역(가격/수량/총액)을 렌더링합니다.
 * @see features/trade/components/order/OrderForm.tsx - OrderForm 매수/매도 탭에서 공용 호출
 */
function OrderInputs({
  type,
  price,
  setPrice,
  quantity,
  setQuantity,
  totalPrice,
  disabled,
  hasError,
  errorMessage,
}: {
  type: "buy" | "sell";
  price: string;
  setPrice: (v: string) => void;
  quantity: string;
  setQuantity: (v: string) => void;
  totalPrice: number;
  disabled: boolean;
  hasError: boolean;
  errorMessage: string | null;
}) {
  const labelClass =
    "text-xs font-medium text-foreground/80 dark:text-brand-100/80 min-w-[56px]";
  const inputClass =
    "col-span-3 h-9 text-right font-mono text-sm dark:border-brand-700/55 dark:bg-black/25 dark:text-brand-100";

  return (
    <div className="space-y-2 sm:space-y-2.5">
      {/* 주문 가능 */}
      <div className="flex items-center justify-between rounded-md bg-muted/30 px-3 py-1.5 text-xs dark:bg-brand-900/25">
        <span className="text-muted-foreground dark:text-brand-100/60">
          주문가능
        </span>
        <span className="font-medium text-foreground dark:text-brand-50">
          - {type === "buy" ? "KRW" : "주"}
        </span>
      </div>

      {hasError && (
        <div className="rounded-md bg-destructive/10 p-2 text-xs text-destructive break-keep">
          {errorMessage}
        </div>
      )}

      {/* 가격 입력 */}
      <div className="grid grid-cols-4 items-center gap-2">
        <span className={labelClass}>
          {type === "buy" ? "매수가격" : "매도가격"}
        </span>
        <Input
          className={inputClass}
          placeholder="0"
          value={price}
          onChange={(e) => setPrice(e.target.value)}
          disabled={disabled}
        />
      </div>

      {/* 수량 입력 */}
      <div className="grid grid-cols-4 items-center gap-2">
        <span className={labelClass}>주문수량</span>
        <Input
          className={inputClass}
          placeholder="0"
          value={quantity}
          onChange={(e) => setQuantity(e.target.value)}
          disabled={disabled}
        />
      </div>

      {/* 총액 */}
      <div className="grid grid-cols-4 items-center gap-2">
        <span className={labelClass}>주문총액</span>
        <Input
          className={cn(inputClass, "bg-muted/40 dark:bg-black/20")}
          value={totalPrice > 0 ? `${totalPrice.toLocaleString()}원` : ""}
          readOnly
          disabled={disabled}
          placeholder="0원"
        />
      </div>
    </div>
  );
}

/**
 * @description 주문 비율(10/25/50/100%) 단축 버튼을 표시합니다.
 * @see features/trade/components/order/OrderForm.tsx - OrderForm setPercent 이벤트 처리
 */
function PercentButtons({ onSelect }: { onSelect: (pct: string) => void }) {
  return (
    <div className="grid grid-cols-4 gap-1.5">
      {["10%", "25%", "50%", "100%"].map((pct) => (
        <Button
          key={pct}
          variant="outline"
          size="sm"
          className="h-8 text-xs font-medium border-border/60 hover:border-brand-300 hover:bg-brand-50/50 hover:text-brand-700 dark:border-brand-700/50 dark:hover:border-brand-500 dark:hover:bg-brand-900/30 dark:hover:text-brand-200"
          onClick={() => onSelect(pct)}
        >
          {pct}
        </Button>
      ))}
    </div>
  );
}

/**
 * @description 선택 종목이 보유 상태일 때 주문 패널 하단에 보유 요약을 표시합니다.
 * @summary UI 흐름: TradeContainer(matchedHolding 계산) -> TradeDashboardContent -> OrderForm -> HoldingInfoPanel 렌더링
 * @see features/trade/components/TradeContainer.tsx - selectedSymbol 기준으로 보유종목 매칭 값을 전달합니다.
 */
function HoldingInfoPanel({
  holding,
}: {
  holding?: DashboardHoldingItem | null;
}) {
  if (!holding) return null;

  const profitToneClass = getHoldingProfitToneClass(holding.profitLoss);

  return (
    <div className="rounded-lg border border-border/65 bg-muted/20 p-3 dark:border-brand-700/45 dark:bg-brand-900/28">
      <p className="mb-2 text-xs font-semibold text-foreground dark:text-brand-50">
        보유 정보
      </p>
      <div className="grid grid-cols-2 gap-x-3 gap-y-1.5 text-xs">
        <HoldingInfoRow label="보유수량" value={`${holding.quantity.toLocaleString("ko-KR")}주`} />
        <HoldingInfoRow
          label="평균단가"
          value={`${holding.averagePrice.toLocaleString("ko-KR")}원`}
        />
        <HoldingInfoRow
          label="평가금액"
          value={`${holding.evaluationAmount.toLocaleString("ko-KR")}원`}
        />
        <HoldingInfoRow
          label="손익"
          value={`${holding.profitLoss >= 0 ? "+" : ""}${holding.profitLoss.toLocaleString("ko-KR")}원`}
          toneClass={profitToneClass}
        />
        <HoldingInfoRow
          label="수익률"
          value={`${holding.profitRate >= 0 ? "+" : ""}${holding.profitRate.toFixed(2)}%`}
          toneClass={profitToneClass}
        />
      </div>
    </div>
  );
}

/**
 * @description 보유정보 카드의 단일 라벨/값 행을 렌더링합니다.
 * @see features/trade/components/order/OrderForm.tsx HoldingInfoPanel
 */
function HoldingInfoRow({
  label,
  value,
  toneClass,
}: {
  label: string;
  value: string;
  toneClass?: string;
}) {
  return (
    <div className="flex min-w-0 items-center justify-between gap-2">
      <span className="text-muted-foreground dark:text-brand-100/70">{label}</span>
      <span className={cn("truncate font-semibold tabular-nums text-foreground dark:text-brand-50", toneClass)}>
        {value}
      </span>
    </div>
  );
}

/**
 * @description 보유 손익 부호에 따른 색상 클래스를 반환합니다.
 * @see features/trade/components/order/OrderForm.tsx HoldingInfoPanel
 */
function getHoldingProfitToneClass(value: number) {
  if (value > 0) return "text-red-500 dark:text-red-400";
  if (value < 0) return "text-blue-600 dark:text-blue-400";
  return "text-foreground dark:text-brand-50";
}
