package catalog

import (
	"context"
	"io"

	"github.com/a-h/templ"

	"xtablo-backend/internal/web/ui"
)

type anyComponent = templ.Component

func buttonExamples() []Example {
	return []Example{
		{
			Title:       "Default solid action",
			Description: "Used for the main action in a page section or modal footer.",
			Preview: ui.Button(ui.ButtonProps{
				Label:   "Nouveau projet",
				Variant: ui.ButtonVariantDefault,
				Size:    ui.SizeMD,
				Type:    "button",
			}),
			Snippet: `@ui.Button(ui.ButtonProps{
	Label:   "Nouveau projet",
	Variant: ui.ButtonVariantDefault,
	Size:    ui.SizeMD,
	Type:    "button",
})`,
		},
		{
			Title:       "Soft warning action",
			Description: "Used for inline actions that need emphasis without the weight of a solid button.",
			Preview: ui.Button(ui.ButtonProps{
				Label:   "Relancer",
				Variant: ui.ButtonVariantWarning,
				Tone:    ui.ButtonToneSoft,
				Size:    ui.SizeMD,
				Type:    "button",
			}),
			Snippet: `@ui.Button(ui.ButtonProps{
	Label:   "Relancer",
	Variant: ui.ButtonVariantWarning,
	Tone:    ui.ButtonToneSoft,
	Size:    ui.SizeMD,
	Type:    "button",
})`,
		},
		{
			Title:       "Soft danger action",
			Description: "Used for irreversible actions after explicit confirmation.",
			Preview: ui.Button(ui.ButtonProps{
				Label:   "Supprimer",
				Variant: ui.ButtonVariantDanger,
				Tone:    ui.ButtonToneSoft,
				Size:    ui.SizeLG,
				Type:    "submit",
			}),
			Snippet: `@ui.Button(ui.ButtonProps{
	Label:   "Supprimer",
	Variant: ui.ButtonVariantDanger,
	Tone:    ui.ButtonToneSoft,
	Size:    ui.SizeLG,
	Type:    "submit",
})`,
		},
	}
}

func tokenExamples() []Example {
	return []Example{
		{
			Title:       "Status tones",
			Description: "Shared semantic badges for info, warning, success, and danger states.",
			Preview: componentFunc(func(ctx context.Context, w io.Writer) error {
				for _, component := range []templ.Component{
					ui.Badge(ui.BadgeProps{Label: "À faire", Variant: ui.BadgeVariantInfo}),
					ui.Badge(ui.BadgeProps{Label: "En cours", Variant: ui.BadgeVariantWarning}),
					ui.Badge(ui.BadgeProps{Label: "Terminé", Variant: ui.BadgeVariantSuccess}),
					ui.Badge(ui.BadgeProps{Label: "Erreur", Variant: ui.BadgeVariantDanger}),
				} {
					if _, err := io.WriteString(w, `<div class="catalog-inline">`); err != nil {
						return err
					}
					if err := component.Render(ctx, w); err != nil {
						return err
					}
					if _, err := io.WriteString(w, `</div>`); err != nil {
						return err
					}
				}
				return nil
			}),
			Snippet: `@ui.Badge(ui.BadgeProps{Label: "En cours", Variant: ui.BadgeVariantWarning})`,
		},
	}
}

func badgeExamples() []Example {
	return []Example{
		{
			Title:       "Status set",
			Description: "The four semantic badge tones used across the app.",
			Preview: componentFunc(func(ctx context.Context, w io.Writer) error {
				return renderInlineComponents(ctx, w,
					ui.Badge(ui.BadgeProps{Label: "À faire", Variant: ui.BadgeVariantInfo}),
					ui.Badge(ui.BadgeProps{Label: "En cours", Variant: ui.BadgeVariantWarning}),
					ui.Badge(ui.BadgeProps{Label: "Terminé", Variant: ui.BadgeVariantSuccess}),
					ui.Badge(ui.BadgeProps{Label: "Erreur", Variant: ui.BadgeVariantDanger}),
				)
			}),
			Snippet: `@ui.Badge(ui.BadgeProps{Label: "En cours", Variant: ui.BadgeVariantWarning})`,
		},
	}
}

func iconButtonExamples() []Example {
	return []Example{
		{
			Title:       "Borderless destructive action",
			Description: "Used for delete controls inside project cards and list rows.",
			Preview: ui.IconButton(ui.IconButtonProps{
				Label:   "Supprimer le projet",
				Icon:    "trash",
				Variant: ui.IconButtonVariantDanger,
				Tone:    ui.IconButtonToneGhost,
				Type:    "button",
			}),
			Snippet: `@ui.IconButton(ui.IconButtonProps{
	Label:   "Supprimer le projet",
	Icon:    "trash",
	Variant: ui.IconButtonVariantDanger,
	Tone:    ui.IconButtonToneGhost,
	Type:    "button",
})`,
		},
		{
			Title:       "Borderless neutral action",
			Description: "Used for lightweight edit or details actions inside cards and list rows.",
			Preview: ui.IconButton(ui.IconButtonProps{
				Label:   "Modifier le projet",
				Icon:    "pencil",
				Variant: ui.IconButtonVariantNeutral,
				Tone:    ui.IconButtonToneGhost,
				Type:    "button",
			}),
			Snippet: `@ui.IconButton(ui.IconButtonProps{
	Label:   "Modifier le projet",
	Icon:    "pencil",
	Variant: ui.IconButtonVariantNeutral,
	Tone:    ui.IconButtonToneGhost,
	Type:    "button",
})`,
		},
	}
}

func inputExamples() []Example {
	return []Example{
		{
			Title:       "Text input",
			Description: "Single-line input for names, titles, and short labels.",
			Preview: ui.Input(ui.InputProps{
				Name:        "name",
				Value:       "Projet Atlas",
				Placeholder: "Nom du projet",
				Type:        "text",
			}),
			Snippet: `@ui.Input(ui.InputProps{
	Name:        "name",
	Value:       "Projet Atlas",
	Placeholder: "Nom du projet",
	Type:        "text",
})`,
		},
		{
			Title:       "Textarea",
			Description: "Multiline field for longer project notes and descriptions.",
			Preview: ui.Textarea(ui.TextareaProps{
				Name:        "description",
				Value:       "Une description de projet plus détaillée.",
				Placeholder: "Description",
				Rows:        4,
			}),
			Snippet: `@ui.Textarea(ui.TextareaProps{
	Name:        "description",
	Value:       "Une description de projet plus détaillée.",
	Placeholder: "Description",
	Rows:        4,
})`,
		},
	}
}

func selectExamples() []Example {
	return []Example{
		{
			Title:       "Single select",
			Description: "Single-choice dropdown with the shared input shell and custom chevron.",
			Preview: ui.Select(ui.SelectProps{
				Name:        "status",
				Placeholder: "Select a status",
				Value:       "in-progress",
				Options: []ui.SelectOption{
					{Value: "todo", Label: "To do"},
					{Value: "in-progress", Label: "In progress"},
					{Value: "done", Label: "Done"},
				},
			}),
			Snippet: `@ui.Select(ui.SelectProps{
	Name:        "status",
	Placeholder: "Select a status",
	Value:       "in-progress",
	Options: []ui.SelectOption{
		{Value: "todo", Label: "To do"},
		{Value: "in-progress", Label: "In progress"},
		{Value: "done", Label: "Done"},
	},
})`,
		},
		{
			Title:       "Multiple select",
			Description: "Multi-value selection with inline pills that stay form-compatible.",
			Preview: ui.Select(ui.SelectProps{
				Name:        "assignee_ids",
				Placeholder: "Select multiple values",
				Multiple:    true,
				Values:      []string{"alice", "bob"},
				Options: []ui.SelectOption{
					{Value: "alice", Label: "Alice"},
					{Value: "bob", Label: "Bob"},
					{Value: "charlie", Label: "Charlie"},
				},
			}),
			Snippet: `@ui.Select(ui.SelectProps{
	Name:        "assignee_ids",
	Placeholder: "Select multiple values",
	Multiple:    true,
	Values:      []string{"alice", "bob"},
	Options: []ui.SelectOption{
		{Value: "alice", Label: "Alice"},
		{Value: "bob", Label: "Bob"},
		{Value: "charlie", Label: "Charlie"},
	},
})`,
		},
	}
}

func formFieldExamples() []Example {
	return []Example{
		{
			Title:       "Field with validation",
			Description: "Wraps a control with label and inline error feedback.",
			Preview: ui.FormField(ui.FormFieldProps{
				Label: "Nom",
				For:   "catalog-name",
				Field: ui.Input(ui.InputProps{
					ID:          "catalog-name",
					Name:        "name",
					Placeholder: "Nom du projet",
					Type:        "text",
				}),
				Error: "Le nom est requis",
			}),
			Snippet: `@ui.FormField(ui.FormFieldProps{
	Label: "Nom",
	For:   "catalog-name",
	Field: ui.Input(ui.InputProps{
		ID:          "catalog-name",
		Name:        "name",
		Placeholder: "Nom du projet",
		Type:        "text",
	}),
	Error: "Le nom est requis",
})`,
		},
	}
}

func modalExamples() []Example {
	return []Example{
		{
			Title:       "Create modal",
			Description: "Shared modal shell with a form body and action footer.",
			Preview: ui.Modal(ui.ModalProps{
				Title: "Créer un projet",
				Body: ui.FormField(ui.FormFieldProps{
					Label: "Nom du projet",
					For:   "modal-name",
					Field: ui.Input(ui.InputProps{
						ID:          "modal-name",
						Name:        "name",
						Placeholder: "Nom du projet",
						Type:        "text",
					}),
				}),
				Actions: componentFunc(func(ctx context.Context, w io.Writer) error {
					return renderComponents(ctx, w,
						ui.Button(ui.ButtonProps{
							Label:   "Annuler",
							Variant: ui.ButtonVariantNeutral,
							Size:    ui.SizeMD,
							Type:    "button",
						}),
						ui.Button(ui.ButtonProps{
							Label:   "Créer le projet",
							Variant: ui.ButtonVariantDefault,
							Size:    ui.SizeMD,
							Type:    "submit",
						}),
					)
				}),
			}),
			Snippet: `@ui.Modal(ui.ModalProps{
	Title: "Créer un projet",
	Body: ui.FormField(...),
	Actions: ui.Button(...),
})`,
		},
	}
}

func spacingExamples() []Example {
	return []Example{
		{
			Title:       "Horizontal spacing",
			Description: "Use SpaceX to insert fixed horizontal gaps between inline or row-aligned components.",
			Preview: componentFunc(func(ctx context.Context, w io.Writer) error {
				if _, err := io.WriteString(w, `<div class="catalog-spacing-row">`); err != nil {
					return err
				}
				for _, component := range []templ.Component{
					ui.Button(ui.ButtonProps{
						Label:   "Précédent",
						Variant: ui.ButtonVariantNeutral,
						Size:    ui.SizeMD,
						Type:    "button",
					}),
					ui.SpaceX(ui.SpaceProps{Size: ui.SpacingStepLG}),
					ui.Button(ui.ButtonProps{
						Label:   "Suivant",
						Variant: ui.ButtonVariantDefault,
						Size:    ui.SizeMD,
						Type:    "button",
					}),
				} {
					if err := component.Render(ctx, w); err != nil {
						return err
					}
				}
				_, err := io.WriteString(w, `</div>`)
				return err
			}),
			Snippet: `@ui.SpaceX(ui.SpaceProps{Size: ui.SpacingStepLG})`,
		},
		{
			Title:       "Vertical spacing",
			Description: "Use SpaceY to insert fixed vertical gaps between stacked blocks.",
			Preview: componentFunc(func(ctx context.Context, w io.Writer) error {
				if _, err := io.WriteString(w, `<div class="catalog-spacing-column">`); err != nil {
					return err
				}
				for _, component := range []templ.Component{
					ui.Card(ui.CardProps{
						Body: textComponent("Bloc 1"),
					}),
					ui.SpaceY(ui.SpaceProps{Size: ui.SpacingStepMD}),
					ui.Card(ui.CardProps{
						Body: textComponent("Bloc 2"),
					}),
				} {
					if err := component.Render(ctx, w); err != nil {
						return err
					}
				}
				_, err := io.WriteString(w, `</div>`)
				return err
			}),
			Snippet: `@ui.SpaceY(ui.SpaceProps{Size: ui.SpacingStepMD})`,
		},
	}
}

func tableExamples() []Example {
	return []Example{
		{
			Title:       "List shell",
			Description: "Shared wrapper for server-rendered resource tables.",
			Preview: ui.Table(ui.TableProps{
				Head: textComponent(`<tr><th class="px-6 py-3 text-left text-xs font-semibold text-gray-600 uppercase tracking-wider">Projet</th><th class="px-6 py-3 text-left text-xs font-semibold text-gray-600 uppercase tracking-wider">Statut</th></tr>`),
				Body: textComponent(`<tr><td class="px-6 py-4">Table View</td><td class="px-6 py-4">En cours</td></tr>`),
			}),
			Snippet: `@ui.Table(ui.TableProps{
	Head: TabloListHead(),
	Body: TabloListBody(tablos),
})`,
		},
	}
}

func emptyStateExamples() []Example {
	return []Example{
		{
			Title:       "Centered empty state",
			Description: "Used when a list has no rows yet and the next action should stay obvious.",
			Preview: ui.EmptyState(ui.EmptyStateProps{
				Title:       "Aucun projet trouvé",
				Description: "Créez votre premier projet",
				Icon:        ui.UIIcon("grid3x3"),
				Action: ui.Button(ui.ButtonProps{
					Label:   "Nouveau projet",
					Variant: ui.ButtonVariantDefault,
					Size:    ui.SizeMD,
					Type:    "button",
					Icon:    "plus",
				}),
			}),
			Snippet: `@ui.EmptyState(ui.EmptyStateProps{
	Title:       "Aucun projet trouvé",
	Description: "Créez votre premier projet",
	Icon:        ui.UIIcon("grid3x3"),
	Action:      ui.Button(...),
})`,
		},
	}
}

func cardExamples() []Example {
	return []Example{
		{
			Title:       "Surface card",
			Description: "Generic elevated surface with optional header and footer.",
			Preview: ui.Card(ui.CardProps{
				Header: textComponent("Header"),
				Body:   textComponent("Body"),
				Footer: textComponent("Footer"),
			}),
			Snippet: `@ui.Card(ui.CardProps{
	Header: textComponent("Header"),
	Body:   textComponent("Body"),
	Footer: textComponent("Footer"),
})`,
		},
	}
}

func componentFunc(fn func(context.Context, io.Writer) error) templ.Component {
	return templ.ComponentFunc(fn)
}

func textComponent(text string) templ.Component {
	return templ.ComponentFunc(func(ctx context.Context, w io.Writer) error {
		_, err := io.WriteString(w, text)
		return err
	})
}

func renderInlineComponents(ctx context.Context, w io.Writer, components ...templ.Component) error {
	for _, component := range components {
		if _, err := io.WriteString(w, `<div class="catalog-inline">`); err != nil {
			return err
		}
		if err := component.Render(ctx, w); err != nil {
			return err
		}
		if _, err := io.WriteString(w, `</div>`); err != nil {
			return err
		}
	}
	return nil
}

func renderComponents(ctx context.Context, w io.Writer, components ...templ.Component) error {
	for _, component := range components {
		if err := component.Render(ctx, w); err != nil {
			return err
		}
	}
	return nil
}
