import { useEffect, useState } from "react";
import type { ApiSettings } from "@govoplan/core-webui";
import { Button } from "@govoplan/core-webui";
import { Card } from "@govoplan/core-webui";
import { FormField } from "@govoplan/core-webui";
import { ToggleSwitch } from "@govoplan/core-webui";
import { fetchSystemSettingsDelta, updateSystemSettings, type LanguagePackage, type PrivacyRetentionLimitPermissions, type PrivacyRetentionPolicy, type SystemSettingsDeltaSections, type SystemSettingsItem } from "../../api/admin";
import { AdminPageLayout, adminErrorMessage, useDeltaWatermarks, useUnsavedDraftGuard } from "@govoplan/core-webui";

const DELTA_KEY = "admin:system-settings";

const defaultAllowLowerLevelLimits: PrivacyRetentionLimitPermissions = {
  store_raw_campaign_json: true,
  raw_campaign_json_retention_days: true,
  generated_eml_retention_days: true,
  stored_report_detail_retention_days: true,
  mock_mailbox_retention_days: true,
  audit_detail_retention_days: true,
  audit_detail_level: true
};

const defaultPrivacyPolicy: PrivacyRetentionPolicy = {
  store_raw_campaign_json: true,
  raw_campaign_json_retention_days: null,
  generated_eml_retention_days: null,
  stored_report_detail_retention_days: null,
  mock_mailbox_retention_days: null,
  audit_detail_retention_days: null,
  audit_detail_level: "full",
  allow_lower_level_limits: defaultAllowLowerLevelLimits
};

const fallback: SystemSettingsItem = {
  default_locale: "en",
  allow_tenant_custom_groups: true,
  allow_tenant_custom_roles: true,
  allow_tenant_api_keys: true,
  privacy_retention_policy: defaultPrivacyPolicy,
  maintenance_mode: { enabled: false, message: "" },
  available_languages: [
    { code: "en", label: "English", native_label: "English" },
    { code: "de", label: "German", native_label: "Deutsch" }
  ],
  enabled_language_codes: ["en", "de"],
  settings: {}
};

export default function SystemSettingsPanel({ settings, canWrite, canAccessMaintenance }: {settings: ApiSettings;canWrite: boolean;canAccessMaintenance: boolean;}) {
  const [draft, setDraft] = useState<SystemSettingsItem>(fallback);
  const [savedDraft, setSavedDraft] = useState<SystemSettingsItem>(fallback);
  const [loading, setLoading] = useState(true);
  const [busy, setBusy] = useState(false);
  const [error, setError] = useState("");
  const [success, setSuccess] = useState("");
  const [packageDraft, setPackageDraft] = useState({ code: "", label: "", nativeLabel: "" });
  const { getDeltaWatermark, setDeltaWatermark, resetDeltaWatermark } = useDeltaWatermarks();
  const defaultLocaleOptions = localeOptions(draft.default_locale, draft.enabled_language_codes);
  const dirty = systemSettingsDraftKey(draft) !== systemSettingsDraftKey(savedDraft);

  useUnsavedDraftGuard({
    dirty,
    onSave: save,
    onDiscard: () => {
      setDraft(savedDraft);
      setPackageDraft({ code: "", label: "", nativeLabel: "" });
    }
  });

  async function load() {
    setLoading(true);
    setError("");
    try {
      const wasDirty = systemSettingsDraftKey(draft) !== systemSettingsDraftKey(savedDraft);
      const response = await fetchSystemSettingsDelta(settings, { since: getDeltaWatermark(DELTA_KEY) });
      setDeltaWatermark(DELTA_KEY, response.watermark);
      if (response.full && response.item) {
        setSavedDraft(response.item);
        if (!wasDirty) setDraft(response.item);
      } else if (response.changed_sections.length) {
        setSavedDraft((current) => applySystemSettingsSections(current, response.sections));
        if (!wasDirty) setDraft((current) => applySystemSettingsSections(current, response.sections));
      }
    }
    catch (err) {setError(adminErrorMessage(err));} finally
    {setLoading(false);}
  }

  useEffect(() => {
    resetDeltaWatermark(DELTA_KEY);
    void load();
  }, [settings.accessToken, settings.apiBaseUrl, resetDeltaWatermark]);

  async function save(): Promise<boolean> {
    setBusy(true);
    setError("");
    try {
      const saved = await updateSystemSettings(settings, {
        default_locale: draft.default_locale,
        allow_tenant_custom_groups: draft.allow_tenant_custom_groups,
        allow_tenant_custom_roles: draft.allow_tenant_custom_roles,
        allow_tenant_api_keys: draft.allow_tenant_api_keys,
        maintenance_mode: draft.maintenance_mode,
        available_languages: draft.available_languages,
        enabled_language_codes: draft.enabled_language_codes
      });
      setDraft(saved);
      setSavedDraft(saved);
      resetDeltaWatermark(DELTA_KEY);
      setSuccess("i18n:govoplan-admin.system_settings_saved.dac4f17b");
      return true;
    } catch (err) {setError(adminErrorMessage(err));return false;} finally
    {setBusy(false);}
  }

  function toggleLanguage(code: string, checked: boolean) {
    const enabled = new Set(draft.enabled_language_codes);
    if (checked) enabled.add(code);
    else enabled.delete(code);
    const nextEnabled = draft.available_languages.map((item) => item.code).filter((item) => enabled.has(item));
    const defaultLocale = nextEnabled.includes(draft.default_locale) ? draft.default_locale : (nextEnabled[0] ?? draft.default_locale);
    setDraft({ ...draft, enabled_language_codes: nextEnabled, default_locale: defaultLocale });
  }

  function installLanguagePackage() {
    const code = normalizeLanguageCode(packageDraft.code);
    if (!code || !packageDraft.label.trim()) return;
    const nextPackage: LanguagePackage = {
      code,
      label: packageDraft.label.trim(),
      native_label: packageDraft.nativeLabel.trim() || packageDraft.label.trim()
    };
    const existing = new Set(draft.available_languages.map((item) => item.code));
    const available = existing.has(code)
      ? draft.available_languages.map((item) => item.code === code ? nextPackage : item)
      : [...draft.available_languages, nextPackage];
    const enabled = draft.enabled_language_codes.includes(code) ? draft.enabled_language_codes : [...draft.enabled_language_codes, code];
    setDraft({ ...draft, available_languages: available, enabled_language_codes: enabled, default_locale: draft.default_locale || code });
    setPackageDraft({ code: "", label: "", nativeLabel: "" });
  }

  return (
    <AdminPageLayout
      title="i18n:govoplan-admin.system_general_settings.7cd662ed"
      description="i18n:govoplan-admin.instance_wide_defaults_and_tenant_governance_cap.096a4f97"
      loading={loading}
      error={error}
      success={success}
      actions={<><Button onClick={() => void load()} disabled={loading}>i18n:govoplan-admin.reload.cce71553</Button><Button variant="primary" onClick={() => void save()} disabled={!canWrite || busy}>{busy ? "i18n:govoplan-admin.saving.56a2285c" : "i18n:govoplan-admin.save_settings.913aba9f"}</Button></>}>

      <div className="admin-settings-form">
        <Card title="i18n:govoplan-admin.defaults_for_newly_created_tenants.9d0f4ccd">
          <FormField label="i18n:govoplan-admin.default_locale.b99d021f">
            <select value={draft.default_locale} onChange={(event) => setDraft({ ...draft, default_locale: event.target.value })} disabled={!canWrite || busy || defaultLocaleOptions.length === 0}>
              {defaultLocaleOptions.map((code) => {
                const language = draft.available_languages.find((item) => item.code === code);
                return <option key={code} value={code}>{languageOptionLabel(language ?? { code, label: code.toUpperCase() })}</option>;
              })}
            </select>
          </FormField>
        </Card>
        <Card title="i18n:govoplan-admin.language_packages">
          <div className="settings-list">
            {draft.available_languages.map((item) => (
              <label className="admin-inline-check" key={item.code}>
                <input
                  type="checkbox"
                  checked={draft.enabled_language_codes.includes(item.code)}
                  disabled={!canWrite || busy || item.code === draft.default_locale}
                  onChange={(event) => toggleLanguage(item.code, event.target.checked)} />
                <span><strong>{item.code.toUpperCase()}</strong> {languageOptionLabel(item)}</span>
              </label>
            ))}
          </div>
          <div className="form-grid">
            <FormField label="i18n:govoplan-admin.language_code">
              <input value={packageDraft.code} disabled={!canWrite || busy} placeholder="fr" onChange={(event) => setPackageDraft({ ...packageDraft, code: event.target.value })} />
            </FormField>
            <FormField label="i18n:govoplan-admin.language_name">
              <input value={packageDraft.label} disabled={!canWrite || busy} placeholder="i18n:govoplan-admin.language_name_placeholder" onChange={(event) => setPackageDraft({ ...packageDraft, label: event.target.value })} />
            </FormField>
            <FormField label="i18n:govoplan-admin.native_language_name">
              <input value={packageDraft.nativeLabel} disabled={!canWrite || busy} placeholder="i18n:govoplan-admin.native_language_name_placeholder" onChange={(event) => setPackageDraft({ ...packageDraft, nativeLabel: event.target.value })} />
            </FormField>
            <div className="button-row compact-actions">
              <Button onClick={installLanguagePackage} disabled={!canWrite || busy || !normalizeLanguageCode(packageDraft.code) || !packageDraft.label.trim()}>i18n:govoplan-admin.install_language_package</Button>
            </div>
          </div>
          <p className="muted small-note">i18n:govoplan-admin.language_packages_help</p>
        </Card>
        <Card title="i18n:govoplan-admin.tenant_administration_capabilities.5d265972">
          <div className="settings-list">
            <ToggleSwitch checked={draft.allow_tenant_custom_groups} onChange={(checked) => setDraft({ ...draft, allow_tenant_custom_groups: checked })} label="i18n:govoplan-admin.allow_tenant_defined_groups_by_default.32099d5a" />
            <ToggleSwitch checked={draft.allow_tenant_custom_roles} onChange={(checked) => setDraft({ ...draft, allow_tenant_custom_roles: checked })} label="i18n:govoplan-admin.allow_tenant_defined_roles_by_default.b1f79ee9" />
            <ToggleSwitch checked={draft.allow_tenant_api_keys} onChange={(checked) => setDraft({ ...draft, allow_tenant_api_keys: checked })} label="i18n:govoplan-admin.allow_tenant_api_keys_by_default.58a6cf17" />
          </div>
          <p className="muted small-note">i18n:govoplan-admin.these_settings_are_enforced_by_the_backend_centr.8112ed6f</p>
        </Card>
        <Card title="i18n:govoplan-admin.maintenance_mode.98cca5c6">
          <div className="settings-list">
            <ToggleSwitch
              checked={draft.maintenance_mode.enabled}
              disabled={!canWrite || !canAccessMaintenance}
              onChange={(checked) => setDraft({ ...draft, maintenance_mode: { ...draft.maintenance_mode, enabled: checked } })}
              label="i18n:govoplan-admin.restrict_authenticated_api_access_to_maintenance.2bc47195" />

          </div>
          <FormField label="i18n:govoplan-admin.maintenance_message.ca62571f">
            <textarea
              rows={3}
              value={draft.maintenance_mode.message ?? ""}
              disabled={!canWrite}
              onChange={(event) => setDraft({ ...draft, maintenance_mode: { ...draft.maintenance_mode, message: event.target.value } })} />

          </FormField>
          <p className="muted small-note">i18n:govoplan-admin.changing_the_maintenance_mode_flag_requires_syst.4492050f</p>
        </Card>
      </div>
</AdminPageLayout>);

}

function normalizeLanguageCode(value: string): string {
  return value.trim().toLowerCase().replace(/_/g, "-").split(/[^a-z0-9]+/).filter(Boolean).join("-");
}

function localeOptions(current: string, enabled: string[]): string[] {
  return [...new Set([current, ...enabled].filter((item) => item && item.trim()))];
}

function languageOptionLabel(language: LanguagePackage): string {
  return `${language.code.toUpperCase()} - ${language.native_label || language.label}`;
}

function systemSettingsDraftKey(item: SystemSettingsItem): string {
  return JSON.stringify({
    default_locale: item.default_locale,
    allow_tenant_custom_groups: item.allow_tenant_custom_groups,
    allow_tenant_custom_roles: item.allow_tenant_custom_roles,
    allow_tenant_api_keys: item.allow_tenant_api_keys,
    maintenance_mode: item.maintenance_mode,
    available_languages: item.available_languages,
    enabled_language_codes: item.enabled_language_codes
  });
}

function applySystemSettingsSections(item: SystemSettingsItem, sections: SystemSettingsDeltaSections): SystemSettingsItem {
  return {
    ...item,
    ...(sections.defaults ?? {}),
    ...(sections.tenant_capabilities ?? {}),
    ...(sections.languages ?? {}),
    ...(sections.privacy_retention_policy ? { privacy_retention_policy: sections.privacy_retention_policy } : {}),
    ...(sections.maintenance_mode ? { maintenance_mode: sections.maintenance_mode } : {}),
    ...(sections.settings ? { settings: sections.settings } : {})
  };
}
