"use client"

import { create } from "zustand"
import { DEFAULT_ULTIAI_ENABLED_TOOLS } from "@/lib/ai/ultiai-tool-groups"
import type { OrgSettingsMeta } from "@/lib/admin-settings/map-api-org-settings"
import type {
  Administrator,
  AuthentikSettings,
  FilePolicySettings,
  IntegrationEntry,
  MailingSettings,
  NextcloudSettings,
  OnlyOfficeSettings,
  RichTextSettings,
  AiAssistantSettings,
  AgendaOrgPolicySettings,
  MeetOrgPolicySettings,
  OrgLLMSettings,
  OrgSearchSettings,
  OrgStorageQuotas,
  PluginEntry,
  TwoFactorPolicy,
  UsageQuotaDefaults,
  IdentityProvidersPolicy,
} from "@/lib/admin-settings/org-settings-types"
import { DEFAULT_MEET_POLICY } from "@/lib/meet/meet-settings-types"
import { DEFAULT_ORG_PLUGINS } from "@/lib/admin-settings/default-plugins"

const DEFAULT_AUTHENTIK: AuthentikSettings = {
  enabled: true,
  api_url: "",
  slug: "ulti-suite",
  client_id: "",
  enforce_sso: true,
  allow_password_fallback: false,
  default_groups: "ulti-users",
}

const DEFAULT_IDENTITY_PROVIDERS: IdentityProvidersPolicy = {
  allow_self_enrollment: true,
  default_login_source: "",
  providers: [],
}

const DEFAULT_TWO_FACTOR: TwoFactorPolicy = {
  required_for_all: false,
  required_for_admins: true,
  allowed_methods: ["totp", "webauthn"],
  grace_period_days: 7,
  remember_device_days: 30,
}

const DEFAULT_STORAGE_QUOTAS: OrgStorageQuotas = {
  default_mail_gib: 5,
  default_drive_gib: 5,
  default_photos_gib: 5,
  warn_threshold_pct: 90,
}

const DEFAULT_USAGE_QUOTAS: UsageQuotaDefaults = {
  llm_requests_per_day: 100,
  llm_tokens_per_month: 500_000,
  search_requests_per_day: 50,
  max_api_tokens_per_user: 10,
  max_webhooks_per_user: 20,
}

const DEFAULT_FILE_POLICIES: FilePolicySettings = {
  max_upload_mib: 512,
  allowed_extensions: "",
  block_executable: true,
  external_sharing: "authenticated",
  default_link_expiry_days: 30,
  virus_scan_enabled: false,
  virustotal_api_key: "",
  retention_trash_days: 30,
  mount_oauth: {
    redirect_uri: "",
    google: { enabled: false, client_id: "", client_secret: "" },
    dropbox: { enabled: false, client_id: "", client_secret: "" },
    microsoft: { enabled: false, client_id: "", client_secret: "" },
  },
}

const DEFAULT_LLM: OrgLLMSettings = {
  default_provider_id: "",
  providers: [],
  enforce_org_providers: false,
  allow_user_override: true,
}

const DEFAULT_SEARCH: OrgSearchSettings = {
  suite_engine: "postgres",
  meilisearch_url: "",
  meilisearch_api_key: "",
  typesense_url: "",
  typesense_api_key: "",
  web_search: { default_provider_id: "brave-default", providers: [] },
  enforce_org_search: false,
}

const DEFAULT_NEXTCLOUD: NextcloudSettings = {
  enabled: false,
  base_url: "",
  admin_user: "",
  admin_password: "",
  drive_enabled: true,
  calendar_enabled: true,
  contacts_enabled: true,
  talk_enabled: false,
}

const DEFAULT_MAILING: MailingSettings = {
  enabled: false,
  smtp_host: "",
  smtp_port: 587,
  smtp_user: "",
  smtp_password: "",
  from_email: "noreply@example.com",
  from_name: "Ulti Suite",
  tls_mode: "starttls",
}

const DEFAULT_ONLYOFFICE: OnlyOfficeSettings = {
  enabled: false,
  document_server_url: "",
  jwt_secret: "",
  jwt_header: "Authorization",
}

const DEFAULT_RICHTEXT: RichTextSettings = {
  enabled: true,
  storage_mode: "sidecar",
  export_mirror_format: "",
  hocuspocus_url: "",
}

const DEFAULT_AI_ASSISTANT: AiAssistantSettings = {
  enabled: false,
  openwebui_internal_url: "",
  public_path: "/ai",
  embed_default_temporary: false,
  default_model: "",
  enabled_tools: [...DEFAULT_ULTIAI_ENABLED_TOOLS],
  chat_sync_enabled: true,
  chat_nc_path: "/.ultimail/ai/chats",
  models: [],
}

const DEFAULT_AGENDA: AgendaOrgPolicySettings = {
  default_theme_mode: "system",
  enforce_org_theme: false,
  default_video_provider: "ultimeet",
  enforce_org_video_provider: false,
  video_provider_api_keys: {},
}

const DEFAULT_MEET: MeetOrgPolicySettings = DEFAULT_MEET_POLICY

const DEFAULT_INTEGRATIONS: IntegrationEntry[] = [
  {
    id: "authentik",
    name: "Authentik",
    description: "SSO, groupes et provisionnement des comptes.",
    enabled: true,
    configured: false,
    href: "/admin/settings/authentication",
  },
  {
    id: "nextcloud",
    name: "Nextcloud",
    description: "Drive, agenda, contacts et Talk.",
    enabled: false,
    configured: false,
    href: "/admin/settings/plugins",
  },
  {
    id: "onlyoffice",
    name: "OnlyOffice",
    description: "Édition de documents dans le navigateur.",
    enabled: false,
    configured: false,
    href: "/admin/settings/plugins",
  },
  {
    id: "smtp",
    name: "Mailing unifié",
    description: "SMTP pour notifications suite (partages, mentions).",
    enabled: false,
    configured: false,
    href: "/admin/settings/mail-domains",
  },
]

type OrgSettingsActions = {
  setAuthentik: (patch: Partial<AuthentikSettings>) => void
  setIdentityProviders: (patch: Partial<IdentityProvidersPolicy>) => void
  setTwoFactor: (patch: Partial<TwoFactorPolicy>) => void
  setStorageQuotas: (patch: Partial<OrgStorageQuotas>) => void
  setUsageQuotas: (patch: Partial<UsageQuotaDefaults>) => void
  setFilePolicies: (patch: Partial<FilePolicySettings>) => void
  setLlm: (patch: Partial<OrgLLMSettings>) => void
  setSearch: (patch: Partial<OrgSearchSettings>) => void
  setNextcloud: (patch: Partial<NextcloudSettings>) => void
  setMailing: (patch: Partial<MailingSettings>) => void
  setOnlyoffice: (patch: Partial<OnlyOfficeSettings>) => void
  setRichtext: (patch: Partial<RichTextSettings>) => void
  setAiAssistant: (patch: Partial<AiAssistantSettings>) => void
  setAgenda: (patch: Partial<AgendaOrgPolicySettings>) => void
  setAdministrators: (admins: Administrator[]) => void
  addAdministrator: (admin: Administrator) => void
  removeAdministrator: (id: string) => void
  updateAdministrator: (id: string, patch: Partial<Administrator>) => void
  setPlugins: (plugins: PluginEntry[]) => void
  togglePlugin: (id: string, enabled: boolean) => void
  setIntegrations: (integrations: IntegrationEntry[]) => void
  toggleIntegration: (id: string, enabled: boolean) => void
  hydrateFromApi: (patch: Partial<{
    authentik: AuthentikSettings
    identityProviders: IdentityProvidersPolicy
    twoFactor: TwoFactorPolicy
    storageQuotas: OrgStorageQuotas
    usageQuotas: UsageQuotaDefaults
    filePolicies: FilePolicySettings
    llm: OrgLLMSettings
    search: OrgSearchSettings
    administrators: Administrator[]
    nextcloud: NextcloudSettings
    mailing: MailingSettings
    onlyoffice: OnlyOfficeSettings
    richtext: RichTextSettings
    aiAssistant: AiAssistantSettings
    agenda: AgendaOrgPolicySettings
    meet: MeetOrgPolicySettings
    plugins: PluginEntry[]
    integrations: IntegrationEntry[]
  }>, meta?: OrgSettingsMeta) => void
  setMeet: (patch: Partial<MeetOrgPolicySettings>) => void
}

export const useOrgSettingsStore = create<
  {
    authentik: AuthentikSettings
    identityProviders: IdentityProvidersPolicy
    twoFactor: TwoFactorPolicy
    storageQuotas: OrgStorageQuotas
    usageQuotas: UsageQuotaDefaults
    filePolicies: FilePolicySettings
    llm: OrgLLMSettings
    search: OrgSearchSettings
    administrators: Administrator[]
    nextcloud: NextcloudSettings
    mailing: MailingSettings
    onlyoffice: OnlyOfficeSettings
    richtext: RichTextSettings
    aiAssistant: AiAssistantSettings
    agenda: AgendaOrgPolicySettings
    meet: MeetOrgPolicySettings
    plugins: PluginEntry[]
    integrations: IntegrationEntry[]
    meta: OrgSettingsMeta | null
    apiSynced: boolean
  } & OrgSettingsActions
>()((set) => ({
      authentik: DEFAULT_AUTHENTIK,
      identityProviders: DEFAULT_IDENTITY_PROVIDERS,
      twoFactor: DEFAULT_TWO_FACTOR,
      storageQuotas: DEFAULT_STORAGE_QUOTAS,
      usageQuotas: DEFAULT_USAGE_QUOTAS,
      filePolicies: DEFAULT_FILE_POLICIES,
      llm: DEFAULT_LLM,
      search: DEFAULT_SEARCH,
      administrators: [],
      nextcloud: DEFAULT_NEXTCLOUD,
      mailing: DEFAULT_MAILING,
      onlyoffice: DEFAULT_ONLYOFFICE,
      richtext: DEFAULT_RICHTEXT,
      aiAssistant: DEFAULT_AI_ASSISTANT,
      agenda: DEFAULT_AGENDA,
      meet: DEFAULT_MEET,
      plugins: DEFAULT_ORG_PLUGINS,
      integrations: DEFAULT_INTEGRATIONS,
      meta: null,
      apiSynced: false,

      setAuthentik: (patch) =>
        set((s) => ({ authentik: { ...s.authentik, ...patch } })),
      setIdentityProviders: (patch) =>
        set((s) => ({
          identityProviders: { ...s.identityProviders, ...patch },
        })),
      setTwoFactor: (patch) =>
        set((s) => ({ twoFactor: { ...s.twoFactor, ...patch } })),
      setStorageQuotas: (patch) =>
        set((s) => ({ storageQuotas: { ...s.storageQuotas, ...patch } })),
      setUsageQuotas: (patch) =>
        set((s) => ({ usageQuotas: { ...s.usageQuotas, ...patch } })),
      setFilePolicies: (patch) =>
        set((s) => ({ filePolicies: { ...s.filePolicies, ...patch } })),
      setLlm: (patch) => set((s) => ({ llm: { ...s.llm, ...patch } })),
      setSearch: (patch) => set((s) => ({ search: { ...s.search, ...patch } })),
      setNextcloud: (patch) =>
        set((s) => ({ nextcloud: { ...s.nextcloud, ...patch } })),
      setMailing: (patch) =>
        set((s) => ({ mailing: { ...s.mailing, ...patch } })),
      setOnlyoffice: (patch) =>
        set((s) => ({ onlyoffice: { ...s.onlyoffice, ...patch } })),
      setRichtext: (patch) =>
        set((s) => ({ richtext: { ...s.richtext, ...patch } })),
      setAiAssistant: (patch) =>
        set((s) => ({ aiAssistant: { ...s.aiAssistant, ...patch } })),
      setAgenda: (patch) => set((s) => ({ agenda: { ...s.agenda, ...patch } })),
      setMeet: (patch) =>
        set((s) => ({
          meet: {
            ...s.meet,
            ...patch,
            post_actions: patch.post_actions
              ? { ...s.meet.post_actions, ...patch.post_actions }
              : s.meet.post_actions,
          },
        })),
      setAdministrators: (administrators) => set({ administrators }),
      addAdministrator: (admin) =>
        set((s) => ({ administrators: [...s.administrators, admin] })),
      removeAdministrator: (id) =>
        set((s) => ({
          administrators: s.administrators.filter((a) => a.id !== id),
        })),
      updateAdministrator: (id, patch) =>
        set((s) => ({
          administrators: s.administrators.map((a) =>
            a.id === id ? { ...a, ...patch } : a
          ),
        })),
      setPlugins: (plugins) => set({ plugins }),
      togglePlugin: (id, enabled) =>
        set((s) => {
          const plugins = s.plugins.map((p) => (p.id === id ? { ...p, enabled } : p))
          if (id === "ai-assistant") {
            return {
              plugins,
              aiAssistant: { ...s.aiAssistant, enabled },
            }
          }
          if (id === "office-editor") {
            return {
              plugins,
              onlyoffice: { ...s.onlyoffice, enabled },
            }
          }
          if (id === "richtext-editor") {
            return {
              plugins,
              richtext: { ...s.richtext, enabled },
            }
          }
          return { plugins }
        }),
      setIntegrations: (integrations) => set({ integrations }),
      toggleIntegration: (id, enabled) =>
        set((s) => ({
          integrations: s.integrations.map((i) =>
            i.id === id ? { ...i, enabled } : i
          ),
        })),
      hydrateFromApi: (patch, meta) =>
        set((s) => ({
          ...s,
          ...patch,
          meta: meta ?? s.meta,
          apiSynced: true,
        })),
}))
