package orgpolicy

import (
	"context"
	"encoding/json"

	"github.com/jackc/pgx/v5"
)

// MeetPostActions configures transcript delivery after a meeting.
type MeetPostActions struct {
	EmailEnabled         bool   `json:"email_enabled"`
	EmailRecipients      string `json:"email_recipients"`
	EmailCustomAddresses string `json:"email_custom_addresses"`
	DriveEnabled         bool   `json:"drive_enabled"`
	DriveFolderPath      string `json:"drive_folder_path"`
	LLMEnabled           bool   `json:"llm_enabled"`
	LLMProviderID        string `json:"llm_provider_id"`
	LLMPrompt            string `json:"llm_prompt"`
	LLMThenEmail         bool   `json:"llm_then_email"`
	LLMThenDrive         bool   `json:"llm_then_drive"`
}

// MeetPolicy is the organisation UltiMeet / transcription policy.
type MeetPolicy struct {
	TranscriptionEnabled    bool            `json:"transcription_enabled"`
	TranscriptionMode       string          `json:"transcription_mode"`
	TranscriptionEngine     string          `json:"transcription_engine"`
	SkynetURL               string          `json:"skynet_url"`
	WhisperModel            string          `json:"whisper_model"`
	ExternalAPIURL          string          `json:"external_api_url"`
	ExternalAPIKey          string          `json:"external_api_key"`
	ExternalAPIProvider     string          `json:"external_api_provider"`
	AutoStartTranscription  bool            `json:"auto_start_transcription"`
	PostActions             MeetPostActions `json:"post_actions"`
}

// PublicMeetPolicy is exposed to authenticated clients (no secrets).
type PublicMeetPolicy struct {
	TranscriptionEnabled   bool   `json:"transcription_enabled"`
	TranscriptionMode      string `json:"transcription_mode"`
	AutoStartTranscription bool   `json:"auto_start_transcription"`
}

func defaultMeetPolicy() map[string]any {
	return map[string]any{
		"transcription_enabled":    false,
		"transcription_mode":       "live",
		"transcription_engine":     "faster_whisper_local",
		"skynet_url":               "http://skynet:8000",
		"whisper_model":            "tiny",
		"external_api_url":         "",
		"external_api_provider":    "openai_compatible",
		"external_api_key":         "",
		"auto_start_transcription": false,
		"post_actions": map[string]any{
			"email_enabled":          false,
			"email_recipients":       "organizer",
			"email_custom_addresses": "",
			"drive_enabled":          true,
			"drive_folder_path":      "/UltiMeet/Transcripts",
			"llm_enabled":            false,
			"llm_provider_id":        "",
			"llm_prompt":             "Résume cette réunion en français : points clés, décisions et actions à suivre.",
			"llm_then_email":         true,
			"llm_then_drive":         true,
		},
	}
}

func (l *Loader) MeetPolicy(ctx context.Context) (MeetPolicy, error) {
	var raw []byte
	err := l.db.QueryRow(ctx, `
		SELECT settings FROM org_settings WHERE id = $1
	`, orgSettingsSingletonID).Scan(&raw)
	if err != nil && err != pgx.ErrNoRows {
		return MeetPolicy{}, err
	}

	stored := map[string]any{}
	if len(raw) > 0 {
		if err := json.Unmarshal(raw, &stored); err != nil {
			return MeetPolicy{}, err
		}
	}

	meet, _ := stored["meet"].(map[string]any)
	if meet == nil {
		meet = defaultMeetPolicy()
	}

	postRaw, _ := meet["post_actions"].(map[string]any)
	if postRaw == nil {
		postRaw, _ = defaultMeetPolicy()["post_actions"].(map[string]any)
	}

	mode, _ := meet["transcription_mode"].(string)
	if mode == "" {
		mode = "live"
	}
	engine, _ := meet["transcription_engine"].(string)
	if engine == "" {
		engine = "faster_whisper_local"
	}
	skynetURL, _ := meet["skynet_url"].(string)
	if skynetURL == "" {
		skynetURL = "http://skynet:8000"
	}
	whisperModel, _ := meet["whisper_model"].(string)
	if whisperModel == "" {
		whisperModel = "tiny"
	}
	provider, _ := meet["external_api_provider"].(string)
	if provider == "" {
		provider = "openai_compatible"
	}
	driveFolder, _ := postRaw["drive_folder_path"].(string)
	if driveFolder == "" {
		driveFolder = "/UltiMeet/Transcripts"
	}
	emailRecipients, _ := postRaw["email_recipients"].(string)
	if emailRecipients == "" {
		emailRecipients = "organizer"
	}
	llmPrompt, _ := postRaw["llm_prompt"].(string)
	if llmPrompt == "" {
		llmPrompt = "Résume cette réunion en français : points clés, décisions et actions à suivre."
	}

	return MeetPolicy{
		TranscriptionEnabled:   boolField(meet, "transcription_enabled"),
		TranscriptionMode:      mode,
		TranscriptionEngine:    engine,
		SkynetURL:              skynetURL,
		WhisperModel:           whisperModel,
		ExternalAPIURL:         stringValue(meet["external_api_url"]),
		ExternalAPIKey:         stringValue(meet["external_api_key"]),
		ExternalAPIProvider:    provider,
		AutoStartTranscription: boolField(meet, "auto_start_transcription"),
		PostActions: MeetPostActions{
			EmailEnabled:         boolField(postRaw, "email_enabled"),
			EmailRecipients:      emailRecipients,
			EmailCustomAddresses: stringValue(postRaw["email_custom_addresses"]),
			DriveEnabled:         boolField(postRaw, "drive_enabled"),
			DriveFolderPath:      driveFolder,
			LLMEnabled:           boolField(postRaw, "llm_enabled"),
			LLMProviderID:        stringValue(postRaw["llm_provider_id"]),
			LLMPrompt:            llmPrompt,
			LLMThenEmail:         boolField(postRaw, "llm_then_email"),
			LLMThenDrive:         boolField(postRaw, "llm_then_drive"),
		},
	}, nil
}

func (l *Loader) PublicMeetPolicy(ctx context.Context) (PublicMeetPolicy, error) {
	policy, err := l.MeetPolicy(ctx)
	if err != nil {
		return PublicMeetPolicy{}, err
	}
	return PublicMeetPolicy{
		TranscriptionEnabled:   policy.TranscriptionEnabled,
		TranscriptionMode:      policy.TranscriptionMode,
		AutoStartTranscription: policy.AutoStartTranscription,
	}, nil
}

func (p MeetPolicy) LiveTranscriptionJWT() bool {
	return p.TranscriptionEnabled && p.TranscriptionMode == "live"
}
