"""Iceberg — hidden quantity execution algorithm.

Only exposes ``display_qty`` at a time. When a slice fills, the next
slice is released. Useful for large orders that should not reveal
full size to the market.
"""

from __future__ import annotations

import math
import time
from typing import Any, Dict, List

from ..models import OrderSubmitRequest
from .base import AlgoSlice, AlgoState, ExecAlgorithm


class IcebergAlgorithm(ExecAlgorithm):
    """Iceberg order — shows only a fraction of the total quantity.

    Params:
        display_qty (float): Visible quantity per slice (required).
    """

    name = "iceberg"

    def generate_slices(
        self, req: OrderSubmitRequest, params: Dict[str, Any]
    ) -> List[AlgoSlice]:
        display_qty = float(params.get("display_qty", 0))
        total_qty = req.qty or 0

        if total_qty <= 0:
            raise ValueError("Iceberg requires qty > 0")
        if display_qty <= 0:
            raise ValueError("Iceberg requires display_qty > 0")

        num_slices = math.ceil(total_qty / display_qty)

        slices: List[AlgoSlice] = []
        remaining = total_qty
        for i in range(num_slices):
            qty = min(display_qty, remaining)
            remaining -= qty
            if qty <= 0:
                break
            slices.append(
                AlgoSlice(
                    seq=i,
                    symbol=req.symbol,
                    side=req.side.value,
                    qty=qty,
                    order_type=req.type.value,
                    limit_price=req.limit_price,
                    scheduled_time=0,
                    status="pending" if i == 0 else "held",
                )
            )
        return slices

    def on_fill(self, state: AlgoState, slice_seq: int, fill_qty: float, fill_price: float) -> None:
        super().on_fill(state, slice_seq, fill_qty, fill_price)
        for s in state.slices:
            if s.status == "held":
                s.status = "pending"
                break
