package server

import (
	"bytes"
	"net/http"
	"net/url"

	"prism/service/integration/signal"
	"prism/service/notification"
	"prism/service/util"
)

type AppListItem struct {
	AppName  string
	Channels []ChannelState
}

type ChannelState struct {
	Channel       string
	Label         string
	Active        bool
	Toggleable    bool
	Subscriptions []SubscriptionItem
}

type SubscriptionItem struct {
	ID       string
	Tooltip  string
	Hostname string
}

func (s *Server) handleFragmentApps(w http.ResponseWriter, r *http.Request) {
	apps, err := s.store.GetAllApps()
	if err != nil {
		util.LogAndError(w, s.logger, "Internal server error", http.StatusInternalServerError, err)
		return
	}

	w.Header().Set("Content-Type", "text/html")

	data := s.buildAppListData(apps)

	var buf bytes.Buffer
	if err := s.fragmentTmpl.ExecuteTemplate(&buf, "app-list.html", data); err != nil {
		util.LogAndError(w, s.logger, "Failed to execute template", http.StatusInternalServerError, err)
		return
	}

	_, _ = w.Write(buf.Bytes())
}

func (s *Server) buildAppListData(apps []notification.App) []AppListItem {
	if len(apps) == 0 {
		return nil
	}

	signalEnabled := s.integrations.Signal != nil && s.integrations.Signal.IsEnabled()
	telegramEnabled := s.integrations.Telegram != nil && s.integrations.Telegram.IsEnabled()
	telegramBotName := ""
	if telegramEnabled {
		handlers := s.integrations.Telegram.GetHandlers()
		if handlers != nil {
			client := handlers.GetClient()
			if client != nil {
				if bot, err := client.GetMe(); err == nil && bot != nil && bot.Username != "" {
					telegramBotName = "@" + bot.Username
				}
			}
		}
	}

	items := make([]AppListItem, 0, len(apps))
	for _, app := range apps {
		channels := []ChannelState{}

		if signalEnabled {
			var signalSub *notification.Subscription
			for i := range app.Subscriptions {
				if app.Subscriptions[i].Channel == notification.ChannelSignal {
					signalSub = &app.Subscriptions[i]
					break
				}
			}

			state := ChannelState{
				Channel:    string(notification.ChannelSignal),
				Label:      notification.ChannelSignal.Label(),
				Active:     signalSub != nil,
				Toggleable: true,
			}

			if signalSub != nil && signalSub.Signal != nil {
				state.Subscriptions = []SubscriptionItem{{
					ID:      signalSub.ID,
					Tooltip: signal.FormatPhoneNumber(signalSub.Signal.Account),
				}}
			}

			channels = append(channels, state)
		}

		if telegramEnabled {
			var telegramSub *notification.Subscription
			for i := range app.Subscriptions {
				if app.Subscriptions[i].Channel == notification.ChannelTelegram {
					telegramSub = &app.Subscriptions[i]
					break
				}
			}

			state := ChannelState{
				Channel:    string(notification.ChannelTelegram),
				Label:      notification.ChannelTelegram.Label(),
				Active:     telegramSub != nil,
				Toggleable: true,
			}

			if telegramSub != nil {
				state.Subscriptions = []SubscriptionItem{{
					ID:      telegramSub.ID,
					Tooltip: telegramBotName,
				}}
			}

			channels = append(channels, state)
		}

		webPushSubs := []SubscriptionItem{}
		for _, sub := range app.Subscriptions {
			if sub.Channel == notification.ChannelWebPush && sub.WebPush != nil {
				item := SubscriptionItem{
					ID:      sub.ID,
					Tooltip: sub.WebPush.Endpoint,
				}
				if u, err := url.Parse(sub.WebPush.Endpoint); err == nil {
					item.Hostname = u.Hostname()
				}
				webPushSubs = append(webPushSubs, item)
			}
		}

		if len(webPushSubs) > 0 {
			channels = append(channels, ChannelState{
				Channel:       string(notification.ChannelWebPush),
				Label:         notification.ChannelWebPush.Label(),
				Active:        true,
				Toggleable:    false,
				Subscriptions: webPushSubs,
			})
		}

		item := AppListItem{
			AppName:  app.AppName,
			Channels: channels,
		}
		items = append(items, item)
	}
	return items
}
