# Message Explainer

The `MessageExplainer` class uses LLMs to explain ISO 8583 messages in plain English.

## Quick Start

```python
from iso8583sim.core.parser import ISO8583Parser
from iso8583sim.llm import MessageExplainer

# Parse a message
parser = ISO8583Parser()
message = parser.parse(raw_message)

# Create explainer
explainer = MessageExplainer()

# Get explanation
explanation = explainer.explain(message)
print(explanation)
```

## Explaining Messages

### From Message Object

```python
from iso8583sim.demo import generate_auth_request
from iso8583sim.llm import MessageExplainer

message = generate_auth_request(
    pan="4111111111111111",
    amount=10000,
    terminal_id="TERM0001",
)

explainer = MessageExplainer()
explanation = explainer.explain(message)
print(explanation)
```

Output:
```
This is an authorization request (MTI 0100) for a $100.00 purchase using a
VISA card ending in 1111. The transaction originated from terminal TERM0001
at a merchant location. The card was read using chip (EMV) technology with
no PIN entry required.

Key fields:
- PAN: 4111111111111111 (VISA)
- Amount: $100.00
- Processing Code: 000000 (Purchase)
- POS Entry Mode: 051 (Chip, no PIN)
```

### From Raw Message String

```python
raw_message = "0100702406C120E09000..."

explanation = explainer.explain(raw_message)
print(explanation)
```

### Verbose Mode

Get detailed field-by-field explanations:

```python
explanation = explainer.explain(message, verbose=True)
print(explanation)
```

Output:
```
## Message Overview
Authorization Request (MTI 0100) from an acquirer...

## Field Details

### Field 2 - Primary Account Number (PAN)
Value: 4111111111111111
This is a VISA card (prefix 4) with 16 digits...

### Field 3 - Processing Code
Value: 000000
Indicates a purchase transaction...

### Field 4 - Amount
Value: 000000010000
Transaction amount of $100.00 (in minor units)...

[Additional fields...]
```

## Explaining Specific Elements

### Response Codes

```python
code_explanation = explainer.explain_response_code("51")
print(code_explanation)
```

Output:
```
Response Code 51: Insufficient Funds

The cardholder's account does not have enough available balance to
complete this transaction. The issuing bank declined the authorization.

Recommended actions:
- Customer should use a different payment method
- Customer could deposit funds if using debit
- Merchant should not force or retry the transaction
```

### Individual Fields

```python
field_explanation = explainer.explain_field(22, "051")
print(field_explanation)
```

Output:
```
Field 22 - POS Entry Mode: 051

This indicates:
- Position 1-2 (05): Chip card read - The card's EMV chip was used
- Position 3 (1): PIN not entered

The transaction used secure chip technology, which provides better
fraud protection than magnetic stripe. No PIN was required, likely
because the amount was below the CVM (Cardholder Verification Method)
limit or the terminal doesn't support PIN entry.
```

## EMV Data Explanation

```python
from iso8583sim.demo import generate_emv_auth

emv_message = generate_emv_auth(
    pan="4111111111111111",
    amount=25000,
    cryptogram="1234567890ABCDEF",
)

explanation = explainer.explain(emv_message, verbose=True)
print(explanation)
```

Output includes EMV tag explanations:
```
## Field 55 - ICC System Related Data (EMV)

Tag 9F26 (Application Cryptogram): 1234567890ABCDEF
- The cryptogram generated by the chip for this transaction
- Used by the issuer to verify transaction authenticity

Tag 9F27 (Cryptogram Information Data): 80
- Value 80 indicates ARQC (Authorization Request Cryptogram)
- The card is requesting online authorization from the issuer

[Additional EMV tags...]
```

## Custom Provider

```python
from iso8583sim.llm import MessageExplainer, get_provider

# Use a specific provider
provider = get_provider("openai")
explainer = MessageExplainer(provider=provider)

# Use a specific model
from iso8583sim.llm.providers.anthropic import AnthropicProvider
provider = AnthropicProvider(model="claude-3-haiku-20240307")
explainer = MessageExplainer(provider=provider)
```

## Batch Explanation

```python
messages = [parse(raw) for raw in raw_messages]

explanations = []
for message in messages:
    explanation = explainer.explain(message)
    explanations.append(explanation)
```

## Error Handling

```python
from iso8583sim.llm import MessageExplainer, LLMError

explainer = MessageExplainer()

try:
    explanation = explainer.explain(message)
except LLMError as e:
    print(f"Failed to explain message: {e}")
    # Fall back to structured output
    for field_num, value in message.fields.items():
        print(f"Field {field_num}: {value}")
```

## API Reference

See [LLM API Reference](../api/llm.md#iso8583simllmexplainer) for complete API documentation.
