/**
 * IcsControls — export the current calendar as an .ics file or import one.
 *
 * The export calls the public ICS feed endpoint with the calendar's `ics_token`
 * (the backend issues a token on first read if missing) and downloads it as a
 * file. The import posts the chosen file to `/api/v1/calendar/import`.
 */

import React, { useRef, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { Button } from '@/components/ui/Button';
import { apiClient } from '@/api/client';
import { importIcsFile, type Calendar } from '@/api/calendar';

export interface IcsControlsProps {
  calendar: Calendar | null;
  onImported?: () => void;
}

function downloadBlob(blob: Blob, filename: string): void {
  const url = window.URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = filename;
  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);
  window.URL.revokeObjectURL(url);
}

export function IcsControls({ calendar, onImported }: IcsControlsProps) {
  const { t } = useTranslation();
  const fileInputRef = useRef<HTMLInputElement>(null);
  const [busy, setBusy] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [message, setMessage] = useState<string | null>(null);

  const handleExport = async () => {
    if (!calendar) return;
    setError(null);
    setMessage(null);
    setBusy(true);
    try {
      // First, fetch the calendar to make sure ics_token exists (backend may
      // auto-generate it on first /ics-feed hit; if we have one already, use it).
      const token = calendar.ics_token;
      const url = token
        ? `/calendar/${calendar.id}/ics-feed?token=${encodeURIComponent(token)}`
        : `/calendar/${calendar.id}/ics-feed`;
      const response = await apiClient.get(url, {
        responseType: 'text',
        transformResponse: [(d: unknown) => d],
      });
      const text = typeof response.data === 'string' ? response.data : String(response.data ?? '');
      const blob = new Blob([text], { type: 'text/calendar;charset=utf-8' });
      const safeName = (calendar.name || 'kalender').replace(/[^a-zA-Z0-9_-]+/g, '_');
      downloadBlob(blob, `${safeName}.ics`);
      setMessage(t('calendar.ics.exportSuccess'));
    } catch (e) {
      setError((e as Error).message ?? t('calendar.ics.importFailed'));
    } finally {
      setBusy(false);
    }
  };

  const handleImportClick = () => {
    fileInputRef.current?.click();
  };

  const handleFileSelected = async (
    e: React.ChangeEvent<HTMLInputElement>
  ) => {
    const file = e.target.files?.[0];
    if (!file) return;
    setError(null);
    setMessage(null);
    setBusy(true);
    try {
      const result = await importIcsFile(file, calendar?.id);
      if (result.errors.length > 0) {
        setMessage(
          t('calendar.ics.importPartial', {
            count: result.entries_created,
            errors: result.errors.length,
          })
        );
      } else {
        setMessage(t('calendar.ics.importSuccess', { count: result.entries_created }));
      }
      onImported?.();
    } catch (err) {
      setError((err as Error).message ?? t('calendar.ics.importFailed'));
    } finally {
      setBusy(false);
      // Reset input so the same file can be re-picked
      if (e.target) e.target.value = '';
    }
  };

  return (
    <div className="flex flex-wrap items-center gap-2" data-testid="ics-controls">
      <Button
        variant="secondary"
        size="sm"
        onClick={handleExport}
        disabled={busy || !calendar}
        data-testid="ics-export"
      >
        {t('calendar.ics.export')}
      </Button>

      <Button
        variant="secondary"
        size="sm"
        onClick={handleImportClick}
        disabled={busy}
        data-testid="ics-import"
      >
        {t('calendar.ics.import')}
      </Button>

      <input
        ref={fileInputRef}
        type="file"
        accept=".ics,text/calendar"
        className="hidden"
        onChange={handleFileSelected}
        data-testid="ics-file-input"
      />

      {message && (
        <span
          className="text-xs text-success-700"
          data-testid="ics-success"
        >
          {message}
        </span>
      )}
      {error && (
        <span className="text-xs text-danger-700" data-testid="ics-error">
          {error}
        </span>
      )}
    </div>
  );
}

export default IcsControls;
