package screens
import (
"context"
"fmt"
"strings"
"time"
"github.com/NicoNex/echotron/v3"
"github.com/TelegramExchange/tgex-backend/tg_bot/backend"
"github.com/TelegramExchange/tgex-backend/tg_bot/bot"
)
type PlacementDetails struct {
ProjectID string
PlacementID string
BackState bot.State
}
func (s *PlacementDetails) Enter(b *bot.Bot, mode bot.RenderMode) {
s.renderDetails(b, mode)
}
func (s *PlacementDetails) renderDetails(b *bot.Bot, mode bot.RenderMode) {
placement, err := b.Backend.GetPlacement(context.Background(), b.Session.JWT, b.Session.WorkspaceID, s.ProjectID, s.PlacementID)
if err != nil {
b.SendNew("❌ Не удалось загрузить размещение", Keyboard())
return
}
placementPost := placement.PlacementPost
text := "Детали размещения\n\n"
channelName := formatChannelName(placement.Channel)
text += fmt.Sprintf("• Канал: %s\n", channelName)
text += fmt.Sprintf("• Статус: %s\n", formatPlacementStatus(placement.Status))
text += fmt.Sprintf("• Ссылка: %s\n", formatInviteLinkType(placement.InviteLinkType))
if placement.Details != nil {
if placement.Details.PlacementType != nil {
text += fmt.Sprintf("• Тип: %s\n", formatPlacementType(*placement.Details.PlacementType))
}
if placement.Details.PlacementAt != nil && *placement.Details.PlacementAt != "" {
text += fmt.Sprintf("• Дата размещения: %s\n", formatDateTime(*placement.Details.PlacementAt))
}
if placement.Details.PaymentAt != nil && *placement.Details.PaymentAt != "" {
text += fmt.Sprintf("• Дата оплаты: %s\n", formatDateTime(*placement.Details.PaymentAt))
}
if placement.Details.Cost != nil {
text += fmt.Sprintf("• Стоимость: %s %.0f₽\n",
formatCostType(placement.Details.Cost.Type),
placement.Details.Cost.Value,
)
}
if placement.Details.CostBeforeBargain != nil {
text += fmt.Sprintf("• До торга: %s %.0f₽\n",
formatCostType(placement.Details.CostBeforeBargain.Type),
placement.Details.CostBeforeBargain.Value,
)
}
if placement.Details.Format != nil && *placement.Details.Format != "" {
text += fmt.Sprintf("• Формат: %s\n", *placement.Details.Format)
}
if placement.Details.Comment != nil && *placement.Details.Comment != "" {
text += fmt.Sprintf("• Комментарий: %s\n", *placement.Details.Comment)
}
}
if placementPost != nil {
text += "\nПост\n"
if placementPost.Post.URL != nil && *placementPost.Post.URL != "" {
text += fmt.Sprintf("• Ссылка на пост: %s\n", *placementPost.Post.URL)
} else {
text += "• Ссылка на пост: не найдена\n"
}
}
keyboard := Keyboard(Row(Button("← Назад", "back")))
b.Render(text, keyboard, mode)
}
func formatChannelName(channel backend.Channel) string {
if channel.Title != nil && *channel.Title != "" {
return *channel.Title
}
if channel.Username != nil && *channel.Username != "" {
return "@" + *channel.Username
}
return "Без названия"
}
func formatInviteLinkType(value string) string {
if value == "approval" {
return "с одобрением"
}
return "публичная"
}
func formatPlacementStatus(status string) string {
normalized := strings.TrimSpace(strings.ToLower(status))
switch normalized {
case "planned":
return "Планируется"
case "approved":
return "Согласовано"
case "rejected":
return "Отклонено"
case "in_progress":
return "В работе"
case "completed":
return "Размещено"
default:
return status
}
}
func formatPlacementType(value string) string {
normalized := strings.TrimSpace(strings.ToLower(value))
switch normalized {
case "self_promo":
return "Самопиар"
case "standard":
return "Стандарт"
default:
return value
}
}
func formatCostType(value string) string {
switch strings.TrimSpace(strings.ToLower(value)) {
case "cpm":
return "СРМ"
default:
return "Фикс"
}
}
func formatDateTime(value string) string {
if value == "" {
return value
}
if parsed, err := time.Parse(time.RFC3339, value); err == nil {
return parsed.Format("02.01.2006 15:04")
}
if parsed, err := time.Parse(time.RFC3339Nano, value); err == nil {
return parsed.Format("02.01.2006 15:04")
}
return value
}
func (s *PlacementDetails) HandleCallback(b *bot.Bot, u *echotron.Update) {
if u.CallbackQuery == nil || u.CallbackQuery.Data == "" {
return
}
switch u.CallbackQuery.Data {
case "back":
if s.BackState != nil {
b.SetState(s.BackState, bot.EditMessage)
}
default:
s.Enter(b, bot.NewMessage)
}
}
func (s *PlacementDetails) HandleMessage(_ *bot.Bot, _ *echotron.Update) { return }
func (s *PlacementDetails) Handle(_ *bot.Bot, _ *echotron.Update) { return }
func (s *PlacementDetails) Exit() {}