import {
  useEffect,
  useMemo,
  useState,
  type ChangeEvent,
  type FormEvent,
} from "react";
import { RefreshCw, Trash2 } from "lucide-react";
import {
  Button,
  ColorPickerField,
  Dialog,
  PasswordField,
  SegmentedControl,
  ToggleSwitch,
  i18nMessage,
  useUnsavedDraftGuard,
  type ApiSettings,
} from "@govoplan/core-webui";
import {
  listCalendarCredentials,
  type CalendarBulkMoveExternalAction,
  type CalendarCalDavAuthType,
  type CalendarCalDavConflictPolicy,
  type CalendarCalDavDiscoveryCandidate,
  type CalendarCalDavDiscoveryPayload,
  type CalendarCalDavSyncDirection,
  type CalendarCollection,
  type CalendarCollectionDeletePayload,
  type CalendarCredentialEnvelope,
  type CalendarDeleteEventAction,
  type CalendarSyncSource,
  type CalendarSyncSourceCreatePayload,
  type CalendarSyncSourceKind,
  type CalendarSyncSourceUpdatePayload,
} from "../../api/calendar";
import {
  DEFAULT_CALENDAR_COLOR,
  calendarDraftKey,
  dateTimeLabel,
  errorText,
  normalizeHexColor,
} from "./calendarViewModel";

export type CalendarSourceMode = "local" | CalendarSyncSourceKind;
type CalendarSourceSwitchMode =
  | "local"
  | "caldav"
  | "ics"
  | "graph"
  | "ews";
export type CalendarCollectionDialogState =
  | { kind: "create" }
  | {
      kind: "edit";
      calendar: CalendarCollection;
      eventCount: number | null;
      loadingEventCount: boolean;
    };
export type CalendarDeleteDialogState = {
  calendar: CalendarCollection;
  eventCount: number | null;
  loadingEventCount: boolean;
};
export type CalendarCalDavFormPayload = {
  collection_url: string;
  dav_url: string;
  display_name: string;
  auth_type: CalendarCalDavAuthType;
  username: string;
  credential_envelope_id: string;
  password: string;
  bearer_token: string;
  sync_enabled: boolean;
  sync_interval_seconds: number;
  sync_direction: CalendarCalDavSyncDirection;
  conflict_policy: CalendarCalDavConflictPolicy;
};
export type CalendarCollectionFormPayload = {
  sourceMode: CalendarSourceMode;
  name: string;
  color: string;
  caldav: CalendarCalDavFormPayload;
};

export function CalendarCollectionDialog({
  state,
  settings,
  source,
  saving,
  syncingSourceId,
  canWrite,
  canDelete,
  canManageSources,
  canSyncSources,
  onCancel,
  onSave,
  onRequestDelete,
  onSync,
  onDiscover














}: {state: CalendarCollectionDialogState;settings: ApiSettings;source: CalendarSyncSource | null;saving: boolean;syncingSourceId: string;canWrite: boolean;canDelete: boolean;canManageSources: boolean;canSyncSources: boolean;onCancel: () => void;onSave: (payload: CalendarCollectionFormPayload) => Promise<boolean>;onRequestDelete: (calendar: CalendarCollection, eventCount: number | null, loadingEventCount: boolean) => void;onSync: (source: CalendarSyncSource, payload?: {password?: string | null;bearer_token?: string | null;force_full?: boolean;}) => Promise<void>;onDiscover: (payload: CalendarCalDavDiscoveryPayload) => Promise<{calendars: CalendarCalDavDiscoveryCandidate[];}>;}) {
  const calendar = state.kind === "edit" ? state.calendar : null;
  const isEdit = Boolean(calendar);
  const [sourceMode, setSourceMode] = useState<CalendarSourceMode>(source ? source.source_kind : "local");
  const [name, setName] = useState(calendar?.name ?? "");
  const [color, setColor] = useState(normalizeHexColor(calendar?.color) || DEFAULT_CALENDAR_COLOR);
  const [davUrl, setDavUrl] = useState(source?.collection_url ?? "");
  const [collectionUrl, setCollectionUrl] = useState(source?.collection_url ?? "");
  const [displayName, setDisplayName] = useState(source?.display_name ?? "");
  const [authType, setAuthType] = useState<CalendarCalDavAuthType>(source?.auth_type ?? "basic");
  const [username, setUsername] = useState(source?.username ?? "");
  const [credentialEnvelopeId, setCredentialEnvelopeId] = useState(source?.credential_envelope_id ?? "");
  const [availableCredentials, setAvailableCredentials] = useState<CalendarCredentialEnvelope[]>([]);
  const [credentialsError, setCredentialsError] = useState("");
  const [password, setPassword] = useState("");
  const [bearerToken, setBearerToken] = useState("");
  const [syncEnabled, setSyncEnabled] = useState(source?.sync_enabled ?? true);
  const [syncIntervalMinutes, setSyncIntervalMinutes] = useState(Math.max(1, Math.round((source?.sync_interval_seconds ?? 900) / 60)));
  const [syncDirection, setSyncDirection] = useState<CalendarCalDavSyncDirection>(source?.sync_direction ?? "two_way");
  const [conflictPolicy, setConflictPolicy] = useState<CalendarCalDavConflictPolicy>(source?.conflict_policy ?? "etag");
  const [discoveredCalendars, setDiscoveredCalendars] = useState<CalendarCalDavDiscoveryCandidate[]>([]);
  const [selectedDiscoveredUrl, setSelectedDiscoveredUrl] = useState(source?.collection_url ?? "");
  const [discovering, setDiscovering] = useState(false);
  const [discoveryError, setDiscoveryError] = useState("");
  const formId = "calendar-collection-form";
  const isExistingSyncSource = isEdit && Boolean(source);
  const canEditSource = canManageSources;
  const canEditMutableSourceSettings = canEditSource && !isExistingSyncSource;
  const effectiveCollectionUrl = (collectionUrl || davUrl).trim();
  const effectiveAuthType = sourceMode === "graph" ? "bearer" : authType;
  const needsSourceSecret = sourceMode !== "local" && (
  effectiveAuthType === "basic" && !source?.has_credential && !credentialEnvelopeId && !password.trim() ||
  effectiveAuthType === "bearer" && !source?.has_credential && !credentialEnvelopeId && !bearerToken.trim());

  const sourceDetailsInvalid = sourceMode !== "local" && (
  !isExistingSyncSource && !canEditSource ||
  canEditSource && (!effectiveCollectionUrl || effectiveAuthType === "basic" && !username.trim() || needsSourceSecret));

  const saveDisabled =
  saving ||
  !canWrite ||
  !name.trim() ||
  sourceDetailsInvalid;

  const syncing = source ? syncingSourceId === source.id : false;

  const collectionDraft = {
    sourceMode,
    name,
    color,
    davUrl,
    collectionUrl,
    displayName,
    authType,
    username,
    credentialEnvelopeId,
    password,
    bearerToken,
    syncEnabled,
    syncIntervalMinutes,
    syncDirection,
    conflictPolicy
  };
  const initialCollectionDraftKey = useMemo(() => calendarDraftKey(collectionDraft), []);
  const collectionDirty = calendarDraftKey(collectionDraft) !== initialCollectionDraftKey;

  useUnsavedDraftGuard({
    dirty: collectionDirty,
    onSave: saveCurrent,
    onDiscard: onCancel
  });

  useEffect(() => {
    if (sourceMode === "local" || !canManageSources) {
      setAvailableCredentials([]);
      setCredentialsError("");
      return;
    }
    let active = true;
    listCalendarCredentials(settings, source?.id)
      .then((response) => {
        if (active) setAvailableCredentials(response.credentials);
      })
      .catch((err) => {
        if (active) {
          setAvailableCredentials([]);
          setCredentialsError(errorText(err));
        }
      });
    return () => {
      active = false;
    };
  }, [canManageSources, settings.accessToken, settings.apiBaseUrl, settings.apiKey, source?.id, sourceMode]);

  function currentPayload(): CalendarCollectionFormPayload {
    return {
      sourceMode,
      name,
      color,
      caldav: {
        collection_url: effectiveCollectionUrl,
        dav_url: davUrl,
        display_name: displayName,
        auth_type: effectiveAuthType,
        username,
        credential_envelope_id: credentialEnvelopeId,
        password,
        bearer_token: bearerToken,
        sync_enabled: syncEnabled,
        sync_interval_seconds: syncIntervalMinutes * 60,
        sync_direction: syncDirection,
        conflict_policy: conflictPolicy
      }
    };
  }

  async function saveCurrent(): Promise<boolean> {
    if (saveDisabled) return false;
    return onSave(currentPayload());
  }

  function submit(formEvent: FormEvent<HTMLFormElement>) {
    formEvent.preventDefault();
    void saveCurrent();
  }

  function selectSourceMode(next: CalendarSourceMode) {
    setSourceMode(next);
    setDiscoveryError("");
    setDiscoveredCalendars([]);
    if (next === "graph") {
      setAuthType("bearer");
      setSyncDirection("inbound");
      if (!davUrl.trim()) handleDavUrlChange("me/calendar");
      return;
    }
    if (next === "ews") {
      setAuthType("basic");
      setSyncDirection("inbound");
      if (!davUrl.trim()) handleDavUrlChange("https://exchange.example.org/EWS/Exchange.asmx");
      return;
    }
    if (next === "ics" || next === "webcal") {
      setAuthType("none");
      setSyncDirection("inbound");
      return;
    }
    if (next === "caldav") {
      setSyncDirection("two_way");
    }
  }

  function handleDavUrlChange(next: string) {
    setDavUrl(next);
    setCollectionUrl(next);
    setSelectedDiscoveredUrl("");
    setDiscoveredCalendars([]);
    setDiscoveryError("");
  }

  function applyDiscoveredCalendar(candidate: CalendarCalDavDiscoveryCandidate) {
    setSelectedDiscoveredUrl(candidate.collection_url);
    setCollectionUrl(candidate.collection_url);
    if (candidate.display_name) {
      if (!isExistingSyncSource) setDisplayName(candidate.display_name);
      if (!isEdit && !name.trim()) setName(candidate.display_name);
    }
    const discoveredColor = normalizeHexColor(candidate.color);
    if (!isEdit && discoveredColor) setColor(discoveredColor);
  }

  function handleDiscoveredCalendarChange(event: ChangeEvent<HTMLSelectElement>) {
    const candidate = discoveredCalendars.find((item) => item.collection_url === event.target.value);
    if (candidate) applyDiscoveredCalendar(candidate);
  }

  async function handleDiscover() {
    const url = davUrl.trim();
    if (!url) return;
    setDiscovering(true);
    setDiscoveryError("");
    try {
      const payload: CalendarCalDavDiscoveryPayload = {
        url,
        source_id: source?.id ?? null,
        auth_type: authType,
        username: authType === "basic" ? username.trim() || null : null
      };
      if (credentialEnvelopeId) payload.credential_ref = credentialEnvelopeRef(credentialEnvelopeId);
      if (!credentialEnvelopeId && authType === "basic" && password.trim()) payload.password = password;
      if (!credentialEnvelopeId && authType === "bearer" && bearerToken.trim()) payload.bearer_token = bearerToken;
      const response = await onDiscover(payload);
      setDiscoveredCalendars(response.calendars);
      if (response.calendars.length > 0) {
        applyDiscoveredCalendar(response.calendars[0]);
      } else {
        setDiscoveryError("i18n:govoplan-calendar.no_calendar_collections_found.6453624a");
      }
    } catch (err) {
      setDiscoveryError(errorText(err));
    } finally {
      setDiscovering(false);
    }
  }

  return (
    <Dialog
      open
      title={isEdit ? "i18n:govoplan-calendar.edit_calendar.a47a2a7a" : "i18n:govoplan-calendar.add_calendar.8fadb5bc"}
      className="calendar-event-dialog"
      footerClassName="calendar-event-dialog-footer"
      closeDisabled={saving}
      onClose={onCancel}
      footer={
      <>
          <div>
            {calendar && canDelete &&
          <Button type="button" variant="danger" onClick={() => onRequestDelete(calendar, state.kind === "edit" ? state.eventCount : null, state.kind === "edit" ? state.loadingEventCount : true)} disabled={saving}>
                <Trash2 size={16} /> {calendarDeleteActionLabel(calendar)}
              </Button>
          }
          </div>
          <div className="calendar-dialog-actions">
            <Button type="button" onClick={onCancel} disabled={saving}>i18n:govoplan-calendar.cancel.77dfd213</Button>
            <Button type="submit" form={formId} variant="primary" disabled={saveDisabled}>{saving ? "i18n:govoplan-calendar.saving.ae7e8875" : isEdit ? "i18n:govoplan-calendar.save.efc007a3" : "i18n:govoplan-calendar.add.61cc55aa"}</Button>
          </div>
        </>
      }>

      <form id={formId} className="calendar-dialog-form" onSubmit={submit}>
        {sourceMode !== "local" && !canManageSources && <p className="calendar-form-note">i18n:govoplan-calendar.managing_sync_sources_requires_calendar_administ.835e29fa</p>}
        {!isEdit &&
        <SegmentedControl
          className="calendar-source-switch"
          size="equal"
          width="fill"
          ariaLabel="i18n:govoplan-calendar.calendar_source_type.92cdb42f"
          value={sourceSwitchMode(sourceMode)}
          disabled={saving}
          onChange={selectSourceMode}
          options={[
            { id: "local", label: "i18n:govoplan-calendar.local.dc99d54d" },
            { id: "caldav", label: "i18n:govoplan-calendar.caldav.64f9720e", disabled: !canManageSources },
            { id: "ics", label: "i18n:govoplan-calendar.ics_webcal.9c55b570", disabled: !canManageSources },
            { id: "graph", label: "i18n:govoplan-calendar.graph.9a7405eb", disabled: !canManageSources },
            { id: "ews", label: "i18n:govoplan-calendar.exchange.5b13eac7", disabled: !canManageSources }
          ]}
        />
        }
        <div className="calendar-dialog-name-color-row">
          <label>
            <span>i18n:govoplan-calendar.name.709a2322</span>
            <input value={name} onChange={(item) => setName(item.target.value)} required maxLength={255} autoFocus disabled={saving || !canWrite} />
          </label>
          <label className="calendar-dialog-color-label">
            <span>i18n:govoplan-calendar.color.1d0c8304</span>
            <ColorPickerField value={color} onChange={setColor} disabled={saving || !canWrite} />
          </label>
        </div>
        {sourceMode === "local" ?
        <section className="calendar-source-pane">
            <h3>i18n:govoplan-calendar.local_calendar.ed3f72f8</h3>
            <p className="calendar-form-note">i18n:govoplan-calendar.events_are_stored_in_govoplan_and_are_not_synced.3660e504</p>
          </section> :

        <section className="calendar-source-pane">
            <div className="calendar-source-pane-heading">
              <h3>{calendarSourcePaneTitle(sourceMode)}</h3>
              {source &&
            <span className={[
            "calendar-sync-status",
            syncing ? "is-syncing" : "",
            source.last_status === "error" && !syncing ? "is-error" : ""].
            filter(Boolean).join(" ")}>
                  {syncing ? "i18n:govoplan-calendar.syncing.4ae6fa22" : source.last_status || "i18n:govoplan-calendar.not_synced.4c205136"}
                </span>
            }
            </div>
            <div className="calendar-caldav-setup">
              <label className="calendar-dialog-wide">
                <span>{calendarSourceUrlLabel(sourceMode)}</span>
                <input
                value={davUrl}
                onChange={(item) => handleDavUrlChange(item.target.value)}
                placeholder={calendarSourceUrlPlaceholder(sourceMode)}
                required
                maxLength={1000}
                disabled={saving || !canEditSource} />

              </label>
              <label>
                <span>i18n:govoplan-calendar.authentication.ee1acfa5</span>
                <select value={effectiveAuthType} onChange={(item) => setAuthType(item.target.value as CalendarCalDavAuthType)} disabled={saving || !canEditSource || sourceMode === "graph"}>
                  {sourceMode !== "graph" && <option value="basic">i18n:govoplan-calendar.basic.aa2c96da</option>}
                  {sourceMode !== "graph" && sourceMode !== "ews" && <option value="none">i18n:govoplan-calendar.none.6eef6648</option>}
                  <option value="bearer">i18n:govoplan-calendar.bearer_token.ffa64bcf</option>
                </select>
              </label>
              {effectiveAuthType !== "none" &&
              <label>
                <span>Reusable credential</span>
                <select
                  value={credentialEnvelopeId}
                  disabled={saving || !canEditSource}
                  onChange={(event) => {
                    const credentialId = event.target.value;
                    setCredentialEnvelopeId(credentialId);
                    setPassword("");
                    setBearerToken("");
                    const credential = availableCredentials.find((item) => item.id === credentialId);
                    const credentialUsername = credential?.public_data?.username;
                    if (credentialUsername) setUsername(String(credentialUsername));
                  }}>
                  <option value="">{source?.has_credential && !source.credential_envelope_id ? "Keep source-specific credential" : "Enter credentials below"}</option>
                  {availableCredentials.map((credential) =>
                    <option key={credential.id} value={credential.id}>
                      {credential.name}{credential.public_data?.username ? ` (${String(credential.public_data.username)})` : ""}
                    </option>
                  )}
                </select>
              </label>
              }
              {credentialsError && <p className="calendar-form-error calendar-dialog-wide">{credentialsError}</p>}
              {effectiveAuthType === "basic" &&
            <>
                  <label>
                    <span>i18n:govoplan-calendar.username.84c29015</span>
                    <input value={username} onChange={(item) => setUsername(item.target.value)} required maxLength={255} disabled={saving || !canEditSource || Boolean(credentialEnvelopeId)} />
                  </label>
                  {!credentialEnvelopeId &&
                  <label>
                    <span>{source?.has_credential ? "i18n:govoplan-calendar.replace_password.3f912c9c" : "i18n:govoplan-calendar.password.8be3c943"}</span>
                    <PasswordField value={password} onValueChange={setPassword} disabled={saving || !canEditSource} autoComplete="new-password" />
                  </label>
                  }
                </>
            }
              {effectiveAuthType === "bearer" && !credentialEnvelopeId &&
            <label>
                  <span>{source?.has_credential ? "i18n:govoplan-calendar.replace_token.bbeee6a9" : "i18n:govoplan-calendar.bearer_token.ffa64bcf"}</span>
                  <PasswordField value={bearerToken} onValueChange={setBearerToken} disabled={saving || !canEditSource} autoComplete="new-password" />
                </label>
            }
              <div className={sourceMode === "caldav" ? "calendar-discovery-actions" : "calendar-discovery-actions is-readonly"}>
                {sourceMode === "caldav" &&
              <Button type="button" onClick={() => void handleDiscover()} disabled={saving || discovering || !canEditSource || !davUrl.trim() || effectiveAuthType === "basic" && !username.trim()}>
                    <RefreshCw size={16} /> {discovering ? "i18n:govoplan-calendar.discovering.1884f689" : "i18n:govoplan-calendar.discover.4827ea22"}
                  </Button>
              }
                {effectiveCollectionUrl && <span>{effectiveCollectionUrl}</span>}
              </div>
            </div>
            {discoveryError && <p className="calendar-form-error">{discoveryError}</p>}
            {sourceMode === "caldav" && discoveredCalendars.length > 0 &&
          <label>
                <span>i18n:govoplan-calendar.calendar.adab5090</span>
                <select value={selectedDiscoveredUrl} onChange={handleDiscoveredCalendarChange} disabled={saving || !canEditSource}>
                  {discoveredCalendars.map((candidate) =>
              <option key={candidate.collection_url} value={candidate.collection_url}>
                      {candidate.display_name || candidate.collection_url}
                    </option>
              )}
                </select>
              </label>
          }
            <details className="calendar-advanced-settings">
              <summary>i18n:govoplan-calendar.advanced.4d064726</summary>
              <div className="calendar-dialog-grid-two">
                <label>
                  <span>i18n:govoplan-calendar.display_name.c7874aaa</span>
                  <input value={displayName} onChange={(item) => setDisplayName(item.target.value)} maxLength={255} disabled={saving || !canEditMutableSourceSettings} />
                </label>
              </div>
              <div className="calendar-sync-settings">
                <ToggleSwitch label="i18n:govoplan-calendar.automatic_sync.084644b2" checked={syncEnabled} disabled={saving || !canEditMutableSourceSettings} onChange={setSyncEnabled} />
                <label>
                  <span>i18n:govoplan-calendar.interval.011efcd5</span>
                  <input type="number" min={1} step={1} value={syncIntervalMinutes} onChange={(item) => setSyncIntervalMinutes(Math.max(1, Number(item.target.value) || 1))} disabled={saving || !canEditMutableSourceSettings} />
                </label>
                <label>
                  <span>i18n:govoplan-calendar.direction.fd8e45ba</span>
                  <select value={sourceMode === "caldav" ? syncDirection : "inbound"} onChange={(item) => setSyncDirection(item.target.value as CalendarCalDavSyncDirection)} disabled={saving || !canEditMutableSourceSettings || sourceMode !== "caldav"}>
                    <option value="two_way">i18n:govoplan-calendar.two_way.ee50a3e6</option>
                    <option value="inbound">i18n:govoplan-calendar.inbound_only.bf4269b0</option>
                  </select>
                </label>
                <label>
                  <span>i18n:govoplan-calendar.conflict_policy.5810e150</span>
                  <select value={conflictPolicy} onChange={(item) => setConflictPolicy(item.target.value as CalendarCalDavConflictPolicy)} disabled={saving || !canEditMutableSourceSettings || sourceMode !== "caldav"}>
                    <option value="etag">i18n:govoplan-calendar.require_matching_etag.0ab1ffe1</option>
                    <option value="overwrite">i18n:govoplan-calendar.overwrite_remote.39625e32</option>
                  </select>
                </label>
              </div>
            </details>
            {source &&
          <div className="calendar-sync-status-panel">
                <dl>
                  <div><dt>i18n:govoplan-calendar.last_attempt.82aee111</dt><dd>{source.last_attempt_at ? dateTimeLabel(new Date(source.last_attempt_at)) : "i18n:govoplan-calendar.never.80c3052d"}</dd></div>
                  <div><dt>i18n:govoplan-calendar.last_sync.ef0ef267</dt><dd>{source.last_synced_at ? dateTimeLabel(new Date(source.last_synced_at)) : "i18n:govoplan-calendar.never.80c3052d"}</dd></div>
                  <div><dt>i18n:govoplan-calendar.next_sync.88c7af72</dt><dd>{source.next_sync_at && source.sync_enabled ? dateTimeLabel(new Date(source.next_sync_at)) : "i18n:govoplan-calendar.not_scheduled.9c367369"}</dd></div>
                  <div><dt>i18n:govoplan-calendar.credential.8bede3ea</dt><dd>{source.has_credential ? "i18n:govoplan-calendar.configured.668c5fff" : "i18n:govoplan-calendar.not_configured.811931bb"}</dd></div>
                </dl>
                {source.last_error && <p className="calendar-form-error">{source.last_error}</p>}
                <div className="calendar-sync-actions">
                  <Button
                type="button"
                className={syncing ? "calendar-sync-button is-syncing" : "calendar-sync-button"}
                onClick={() => void onSync(source, syncTransientPayload(effectiveAuthType, password, bearerToken))}
                disabled={saving || syncing || !canSyncSources}>

                    <RefreshCw size={16} className={syncing ? "calendar-sync-spin" : undefined} /> {syncing ? "i18n:govoplan-calendar.syncing.e5c7727a" : "i18n:govoplan-calendar.sync_now.2b7d938e"}
                  </Button>
                  <Button type="button" onClick={() => void onSync(source, { ...syncTransientPayload(effectiveAuthType, password, bearerToken), force_full: true })} disabled={saving || syncing || !canSyncSources}>
                    i18n:govoplan-calendar.full_sync.21b89c76
                  </Button>
                </div>
              </div>
          }
            {needsSourceSecret && <p className="calendar-form-note">i18n:govoplan-calendar.enter_a_password_or_token_for_this_source.74c09a54</p>}
          </section>
        }
      </form>
    </Dialog>);

}

export function CalendarCollectionDeleteDialog({
  state,
  calendars,
  syncSources,
  saving,
  onCancel,
  onDelete






}: {state: CalendarDeleteDialogState;calendars: CalendarCollection[];syncSources: CalendarSyncSource[];saving: boolean;onCancel: () => void;onDelete: (calendar: CalendarCollection, payload: CalendarCollectionDeletePayload) => Promise<void>;}) {
  const { calendar, eventCount, loadingEventCount } = state;
  const syncSourceByCalendarId = new Map(syncSources.map((source) => [source.calendar_id, source]));
  const source = syncSourceByCalendarId.get(calendar.id) ?? null;
  const moveTargets = calendars.filter((item) =>
  item.id !== calendar.id && calendarMoveTargetIsSupported(source, syncSourceByCalendarId.get(item.id) ?? null)
  );
  const firstMoveTargetId = moveTargets[0]?.id || "";
  const hasEvents = (eventCount ?? 0) > 0;
  const canMoveEvents = hasEvents && moveTargets.length > 0;
  const [eventAction, setEventAction] = useState<CalendarDeleteEventAction>("delete");
  const [targetCalendarId, setTargetCalendarId] = useState(firstMoveTargetId);
  const [makeTargetDefault, setMakeTargetDefault] = useState(calendar.is_default && Boolean(firstMoveTargetId));
  const effectiveEventAction: CalendarDeleteEventAction = canMoveEvents ? eventAction : "delete";
  const confirmDisabled = saving || loadingEventCount || canMoveEvents && effectiveEventAction === "move" && !targetCalendarId;
  const actionLabel = calendarDeleteActionLabel(calendar);
  const targetSource = syncSourceByCalendarId.get(targetCalendarId) ?? null;
  const externalAction = calendarBulkMoveExternalAction(source, targetSource);

  function confirm() {
    void onDelete(calendar, {
      event_action: effectiveEventAction,
      target_calendar_id: effectiveEventAction === "move" ? targetCalendarId : null,
      make_target_default: effectiveEventAction === "move" && calendar.is_default && makeTargetDefault,
      external_action: effectiveEventAction === "move" ? externalAction : null
    });
  }

  return (
    <Dialog
      open
      role="alertdialog"
      title={`${actionLabel} calendar`}
      className="calendar-delete-dialog"
      footerClassName="calendar-event-dialog-footer"
      closeDisabled={saving}
      onClose={onCancel}
      footer={
      <>
          <Button type="button" onClick={onCancel} disabled={saving}>i18n:govoplan-calendar.cancel.77dfd213</Button>
          <Button type="button" variant="danger" onClick={confirm} disabled={confirmDisabled}>
            <Trash2 size={16} /> {saving ? "i18n:govoplan-calendar.working.049ac820" : actionLabel}
          </Button>
        </>
      }>

      <div className="calendar-delete-dialog-body">
        <p className="calendar-delete-warning">
          {loadingEventCount ?
          "i18n:govoplan-calendar.loading_event_count.716ad3c2" :
          calendarDeleteWarning(calendar, eventCount ?? 0, effectiveEventAction, targetCalendarId, moveTargets)}
        </p>
        {!loadingEventCount && eventCount === null && <p className="calendar-form-note">i18n:govoplan-calendar.event_count_could_not_be_loaded_the_backend_will.163ff055</p>}
        {canMoveEvents &&
        <fieldset className="calendar-delete-options" disabled={saving || loadingEventCount}>
            <legend>{eventCount} event{eventCount === 1 ? "" : "s"}</legend>
            <label>
              <input
              type="radio"
              name="calendar-delete-event-action"
              value="delete"
              checked={eventAction === "delete"}
              onChange={() => setEventAction("delete")} />

              <span>{calendarEventDeleteOptionLabel(calendar)}</span>
            </label>
            <label>
              <input
              type="radio"
              name="calendar-delete-event-action"
              value="move"
              checked={eventAction === "move"}
              onChange={() => setEventAction("move")} />

              <span>{calendarBulkMoveOptionLabel(externalAction)}</span>
            </label>
            {eventAction === "move" &&
          <>
                <label className="calendar-delete-target-label">
                  <span>i18n:govoplan-calendar.target_calendar.e533fe1d</span>
                  <select value={targetCalendarId} onChange={(item) => setTargetCalendarId(item.target.value)} required>
                    {moveTargets.map((item) =>
                <option key={item.id} value={item.id}>{item.name}</option>
                )}
                  </select>
                </label>
                {calendar.is_default &&
                  <ToggleSwitch label="i18n:govoplan-calendar.make_target_calendar_the_default.10a3977b" checked={makeTargetDefault} onChange={setMakeTargetDefault} />
            }
                <p className="calendar-form-note">{calendarBulkMoveConsequence(externalAction)}</p>
              </>
          }
          </fieldset>
        }
        {!loadingEventCount && hasEvents && moveTargets.length === 0 &&
        <p className="calendar-form-note">{source ?
          "i18n:govoplan-calendar.no_local_target_calendar_is_available_add_a_local_.fad3cb65" :
          "i18n:govoplan-calendar.no_compatible_target_calendar_is_available_add_a_l.1cf6e47b"}</p>
        }
      </div>
    </Dialog>);

}


export function syncSourceCreatePayload(sourceMode: CalendarSourceMode, payload: CalendarCalDavFormPayload): Omit<CalendarSyncSourceCreatePayload, "calendar_id"> {
  const sourceKind = syncSourceKindForMode(sourceMode, payload.collection_url);
  const result: Omit<CalendarSyncSourceCreatePayload, "calendar_id"> = {
    source_kind: sourceKind,
    collection_url: payload.collection_url.trim(),
    display_name: payload.display_name.trim() || null,
    auth_type: sourceKind === "graph" ? "bearer" : payload.auth_type,
    username: sourceKind !== "graph" && payload.auth_type === "basic" ? payload.username.trim() || null : null,
    sync_enabled: payload.sync_enabled,
    sync_interval_seconds: Math.max(60, payload.sync_interval_seconds),
    sync_direction: sourceKind === "caldav" ? payload.sync_direction : "inbound",
    conflict_policy: payload.conflict_policy,
    metadata: {}
  };
  if (payload.credential_envelope_id) {
    result.credential_ref = credentialEnvelopeRef(payload.credential_envelope_id);
  } else if (result.auth_type === "basic" && payload.password.trim()) {
    result.password = payload.password;
  } else if (result.auth_type === "bearer" && payload.bearer_token.trim()) {
    result.bearer_token = payload.bearer_token;
  }
  return result;
}

export function syncSourceConnectionUpdatePayload(payload: CalendarCalDavFormPayload): CalendarSyncSourceUpdatePayload {
  const result: CalendarSyncSourceUpdatePayload = {
    collection_url: payload.collection_url.trim(),
    auth_type: payload.auth_type,
    username: payload.auth_type === "basic" ? payload.username.trim() || null : null
  };
  if (payload.credential_envelope_id) {
    result.credential_ref = credentialEnvelopeRef(payload.credential_envelope_id);
  } else if (payload.auth_type === "basic" && payload.password.trim()) {
    result.password = payload.password;
  } else if (payload.auth_type === "bearer" && payload.bearer_token.trim()) {
    result.bearer_token = payload.bearer_token;
  }
  return result;
}

function credentialEnvelopeRef(credentialId: string): string {
  return `credential-envelope:${credentialId}`;
}

function syncSourceKindForMode(sourceMode: CalendarSourceMode, collectionUrl: string): CalendarSyncSourceKind {
  if (sourceMode === "ics" && collectionUrl.trim().toLowerCase().startsWith("webcal://")) return "webcal";
  return sourceMode === "local" ? "caldav" : sourceMode;
}

function sourceSwitchMode(sourceMode: CalendarSourceMode): CalendarSourceSwitchMode {
  return sourceMode === "webcal" ? "ics" : sourceMode;
}

function syncTransientPayload(authType: CalendarCalDavAuthType, password: string, bearerToken: string) {
  if (authType === "basic" && password.trim()) return { password };
  if (authType === "bearer" && bearerToken.trim()) return { bearer_token: bearerToken };
  return {};
}

function calendarSourcePaneTitle(sourceMode: CalendarSourceMode): string {
  if (sourceMode === "caldav") return "i18n:govoplan-calendar.caldav_source.459ed16a";
  if (sourceMode === "ics" || sourceMode === "webcal") return "i18n:govoplan-calendar.ics_webcal_subscription.03bc0d63";
  if (sourceMode === "graph") return "i18n:govoplan-calendar.microsoft_graph_source.ec4f1383";
  if (sourceMode === "ews") return "i18n:govoplan-calendar.exchange_web_services_source.53caabf3";
  return "i18n:govoplan-calendar.local_calendar.ed3f72f8";
}

function calendarSourceUrlLabel(sourceMode: CalendarSourceMode): string {
  if (sourceMode === "caldav") return "i18n:govoplan-calendar.dav_url.4205e180";
  if (sourceMode === "graph") return "i18n:govoplan-calendar.graph_calendar_url.e59607f3";
  if (sourceMode === "ews") return "i18n:govoplan-calendar.ews_endpoint.a3273983";
  return "i18n:govoplan-calendar.subscription_url.b8b6a1a0";
}

function calendarSourceUrlPlaceholder(sourceMode: CalendarSourceMode): string {
  if (sourceMode === "caldav") return "https://cloud.example.org/remote.php/dav";
  if (sourceMode === "graph") return "me/calendar or https://graph.microsoft.com/v1.0/me/calendar/events/delta";
  if (sourceMode === "ews") return "https://exchange.example.org/EWS/Exchange.asmx";
  return "webcal://example.org/calendar.ics or https://example.org/calendar.ics";
}

function calendarDeleteActionLabel(calendar: CalendarCollection): string {
  return calendarIsExternal(calendar) ? "i18n:govoplan-calendar.remove.e963907d" : "i18n:govoplan-calendar.delete.f6fdbe48";
}

function calendarEventDeleteOptionLabel(calendar: CalendarCollection): string {
  return calendarIsExternal(calendar) ? "i18n:govoplan-calendar.remove_local_events_with_this_calendar.fb8831e1" : "i18n:govoplan-calendar.delete_events_with_this_calendar.cc0e1287";
}

function calendarMoveTargetIsSupported(
source: CalendarSyncSource | null,
targetSource: CalendarSyncSource | null)
: boolean {
  if (source) return targetSource === null;
  return targetSource === null || calendarSyncSourceAcceptsCopies(targetSource);
}

function calendarSyncSourceAcceptsCopies(source: CalendarSyncSource): boolean {
  return source.source_kind === "caldav" && source.sync_enabled && source.sync_direction === "two_way";
}

function calendarBulkMoveExternalAction(
source: CalendarSyncSource | null,
targetSource: CalendarSyncSource | null)
: CalendarBulkMoveExternalAction | undefined {
  if (source && !targetSource) return "detach_keep_remote";
  if (!source && targetSource && calendarSyncSourceAcceptsCopies(targetSource)) return "copy_to_remote";
  return undefined;
}

function calendarBulkMoveOptionLabel(action: CalendarBulkMoveExternalAction | undefined): string {
  if (action === "detach_keep_remote") return "i18n:govoplan-calendar.detach_local_events_and_keep_remote_events.c58ad4e7";
  if (action === "copy_to_remote") return "i18n:govoplan-calendar.move_and_copy_events_to_the_external_calendar.23c3a004";
  return "i18n:govoplan-calendar.move_events_to_another_calendar.830c7b09";
}

function calendarBulkMoveConsequence(action: CalendarBulkMoveExternalAction | undefined): string {
  if (action === "detach_keep_remote") return "i18n:govoplan-calendar.govoplan_moves_the_local_event_copies_to_the_targe.4863e46b";
  if (action === "copy_to_remote") return "i18n:govoplan-calendar.govoplan_moves_the_events_locally_and_queues_durab.da075b16";
  return "i18n:govoplan-calendar.events_remain_in_govoplan_no_external_calendar_is_.62cb5937";
}

function calendarDeleteWarning(
calendar: CalendarCollection,
eventCount: number,
eventAction: CalendarDeleteEventAction,
targetCalendarId: string,
moveTargets: CalendarCollection[])
: string {
  const action = calendarIsExternal(calendar) ? "i18n:govoplan-calendar.removing.b7d2c38b" : "i18n:govoplan-calendar.deleting.2cda36c9";
  const eventWord = eventCount === 1 ? "i18n:govoplan-calendar.event" : "i18n:govoplan-calendar.events";
  if (eventAction === "move") {
    const target = moveTargets.find((item) => item.id === targetCalendarId);
    return i18nMessage("i18n:govoplan-calendar.value_this_calendar_will_move_value_value_to_val.6c87e1c1", { value0: action, value1: eventCount, value2: eventWord, value3: target?.name || "i18n:govoplan-calendar.the_selected_calendar.67caa12f" });
  }
  if (calendarIsExternal(calendar)) {
    return i18nMessage("i18n:govoplan-calendar.value_this_calendar_will_remove_value_local_valu.8f21a59e", { value0: action, value1: eventCount, value2: eventWord });
  }
  return i18nMessage("i18n:govoplan-calendar.value_this_calendar_will_delete_value_value.7869d1f1", { value0: action, value1: eventCount, value2: eventWord });
}

function calendarIsExternal(calendar: CalendarCollection): boolean {
  const metadata = calendar.metadata;
  if (!metadata || typeof metadata !== "object") return false;
  const sourceKind = metadataText(metadata, "source_kind") || metadataText(metadata, "sourceKind") || metadataText(metadata, "connector_kind") || metadataText(metadata, "connectorKind");
  if (sourceKind && sourceKind !== "local") return true;
  const connectionKind = metadataText(metadata, "connection_kind") || metadataText(metadata, "connectionKind");
  if (connectionKind && connectionKind !== "local") return true;
  return Boolean(
    metadataFlag(metadata, "external") ||
    metadataFlag(metadata, "remote") ||
    metadataFlag(metadata, "sync") ||
    metadataFlag(metadata, "caldav") ||
    metadataText(metadata, "connector_id") ||
    metadataText(metadata, "connectorId") ||
    metadataText(metadata, "sync_href") ||
    metadataText(metadata, "syncHref")
  );
}

function metadataText(metadata: Record<string, unknown>, key: string): string {
  const value = metadata[key];
  return typeof value === "string" ? value.trim().toLowerCase() : "";
}

function metadataFlag(metadata: Record<string, unknown>, key: string): boolean {
  return metadata[key] === true;
}
