# i18n Package Refactor Design

## Goal
Refactor pkg/i18n to be extensible without breaking changes in future. Based on Gemini review recommendations.

## File Structure

### Renamed/Merged
| Current | New | Reason |
|---------|-----|--------|
| `interfaces.go` | `types.go` | Contains types, not interfaces |
| `mutate.go` | `loader.go` | Loads/flattens JSON |
| `actions.go` | `hooks.go` | Missing key callbacks |
| `checks.go` | (merge into loader.go) | Loading helpers |
| `mode.go` | (merge into types.go) | Just one type |

### New Files
| File | Purpose |
|------|---------|
| `handler.go` | KeyHandler interface + built-in handlers |
| `context.go` | TranslationContext + C() helper |

### Unchanged
`grammar.go`, `language.go`, `localise.go`, `debug.go`, `numbers.go`, `time.go`, `i18n.go`, `intents.go`, `compose.go`, `transform.go`

## Interfaces

### KeyHandler
```go
// KeyHandler processes translation keys before standard lookup.
type KeyHandler interface {
    Match(key string) bool
    Handle(key string, args []any, next func() string) string
}
```

Built-in handlers:
- `LabelHandler` - `i18n.label.*` → "Status:"
- `ProgressHandler` - `i18n.progress.*` → "Building..."
- `CountHandler` - `i18n.count.*` → "5 files"
- `NumericHandler` - `i18n.numeric.*` → formatted numbers
- `DoneHandler` - `i18n.done.*` → "File deleted"
- `FailHandler` - `i18n.fail.*` → "Failed to delete file"

### Loader
```go
// Loader provides translation data to the Service.
type Loader interface {
    Load(lang string) (map[string]Message, *GrammarData, error)
    Languages() []string
}
```

Built-in: `FSLoader` for embedded/filesystem JSON.

### TranslationContext
```go
type TranslationContext struct {
    Context   string
    Gender    string
    Formality Formality
    Extra     map[string]any
}

func C(context string) *TranslationContext
```

## Service Changes

```go
type Service struct {
    loader       Loader
    messages     map[string]map[string]Message
    grammar      map[string]*GrammarData
    currentLang  string
    fallbackLang string
    formality    Formality
    mode         Mode
    debug        bool
    handlers     []KeyHandler
    mu           sync.RWMutex
}
```

### Constructors
```go
func New() (*Service, error)
func NewWithLoader(loader Loader, opts ...Option) (*Service, error)

type Option func(*Service)
func WithDefaultHandlers() Option
func WithFallback(lang string) Option
func WithFormality(f Formality) Option
```

### T() Flow
1. Parse args → extract Context, Subject, data
2. Run handler chain (each can handle or call next)
3. Standard lookup with context suffix fallback

## Public API

### Keep
- `T(key, args...)`, `Raw(key, args...)`
- `S(noun, value)` - Subject builder
- `SetLanguage()`, `CurrentLanguage()`, `SetMode()`, `CurrentMode()`
- `SetFormality()`, `SetDebug()`, `Direction()`, `IsRTL()`
- Grammar: `PastTense()`, `Gerund()`, `Pluralize()`, `Article()`, `Title()`, `Label()`, `Progress()`

### Add
- `C(context)` - Context builder
- `NewWithLoader()` - Custom loader support
- `AddHandler()`, `PrependHandler()` - Custom handlers

### Remove (No Aliases)
- `NewSubject()` - use `S()`
- `N()` - use `T("i18n.numeric.*")`

## Breaking Changes
- Constructor signature changes
- Internal file reorganisation
- No backwards compatibility layer

## Implementation Order
1. Create new files (types.go, handler.go, loader.go, context.go, hooks.go)
2. Move types from interfaces.go → types.go
3. Implement Loader interface + FSLoader
4. Implement KeyHandler interface + built-in handlers
5. Implement TranslationContext
6. Update Service struct + constructors
7. Update T() to use handler chain
8. Update package-level functions in i18n.go
9. Delete old files
10. Update tests
