/**
 * useRbacExportImport Hook
 * 
 * Hook for exporting and importing RBAC configurations.
 * Supports mandate-level and global (template) exports.
 */

import { useState, useCallback } from 'react';
import api from '../api';

// =============================================================================
// TYPES
// =============================================================================

export type ImportMode = 'merge' | 'replace' | 'add_only';

export interface RbacExportScope {
  type: 'global' | 'mandate' | 'instance';
  mandateId?: string;
  mandateName?: string;
  featureInstanceId?: string;
  featureCode?: string;
  instanceLabel?: string;
}

export interface RbacExportRole {
  roleLabel: string;
  description?: { [key: string]: string };
  featureCode?: string;
}

export interface RbacExportRule {
  roleLabel: string;
  context: 'DATA' | 'UI' | 'RESOURCE';
  item: string | null;
  view: boolean;
  read?: string | null;
  create?: string | null;
  update?: string | null;
  delete?: string | null;
}

export interface RbacExport {
  version: string;
  exportedAt: string;
  exportedBy?: string;
  scope: RbacExportScope;
  roles: RbacExportRole[];
  accessRules: RbacExportRule[];
}

export interface RbacImportResult {
  status: 'success' | 'error';
  mode: ImportMode;
  rolesCreated: number;
  rolesUpdated: number;
  rulesCreated: number;
  rulesUpdated: number;
  errors?: string[];
}

// =============================================================================
// HOOK
// =============================================================================

export function useRbacExportImport() {
  const [exporting, setExporting] = useState(false);
  const [importing, setImporting] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [lastExport, setLastExport] = useState<RbacExport | null>(null);
  const [lastImportResult, setLastImportResult] = useState<RbacImportResult | null>(null);

  /**
   * Export RBAC configuration for a mandate
   */
  const exportMandateRbac = useCallback(async (
    mandateId: string,
    featureCode?: string
  ): Promise<{ success: boolean; data?: RbacExport; error?: string }> => {
    setExporting(true);
    setError(null);
    try {
      const params = new URLSearchParams();
      if (featureCode) params.append('featureCode', featureCode);
      
      const url = `/api/mandates/${mandateId}/rbac/export${params.toString() ? '?' + params.toString() : ''}`;
      const response = await api.get(url);
      
      setLastExport(response.data);
      return { success: true, data: response.data };
    } catch (err: any) {
      const errorMessage = err.response?.data?.detail || err.message || 'Failed to export RBAC';
      setError(errorMessage);
      return { success: false, error: errorMessage };
    } finally {
      setExporting(false);
    }
  }, []);

  /**
   * Export global RBAC templates (SysAdmin only)
   */
  const exportGlobalRbac = useCallback(async (
    featureCode?: string
  ): Promise<{ success: boolean; data?: RbacExport; error?: string }> => {
    setExporting(true);
    setError(null);
    try {
      const params = new URLSearchParams();
      if (featureCode) params.append('featureCode', featureCode);
      
      const url = `/api/admin/rbac/global/export${params.toString() ? '?' + params.toString() : ''}`;
      const response = await api.get(url);
      
      setLastExport(response.data);
      return { success: true, data: response.data };
    } catch (err: any) {
      const errorMessage = err.response?.data?.detail || err.message || 'Failed to export global RBAC';
      setError(errorMessage);
      return { success: false, error: errorMessage };
    } finally {
      setExporting(false);
    }
  }, []);

  /**
   * Export feature instance RBAC
   */
  const exportInstanceRbac = useCallback(async (
    instanceId: string
  ): Promise<{ success: boolean; data?: RbacExport; error?: string }> => {
    setExporting(true);
    setError(null);
    try {
      const response = await api.get(`/api/features/instances/${instanceId}/rbac/export`);
      
      setLastExport(response.data);
      return { success: true, data: response.data };
    } catch (err: any) {
      const errorMessage = err.response?.data?.detail || err.message || 'Failed to export instance RBAC';
      setError(errorMessage);
      return { success: false, error: errorMessage };
    } finally {
      setExporting(false);
    }
  }, []);

  /**
   * Import RBAC configuration into a mandate
   */
  const importMandateRbac = useCallback(async (
    mandateId: string,
    data: RbacExport,
    mode: ImportMode = 'merge'
  ): Promise<{ success: boolean; result?: RbacImportResult; error?: string }> => {
    setImporting(true);
    setError(null);
    try {
      const response = await api.post(
        `/api/mandates/${mandateId}/rbac/import?mode=${mode}`,
        data
      );
      
      setLastImportResult(response.data);
      return { success: true, result: response.data };
    } catch (err: any) {
      const errorMessage = err.response?.data?.detail || err.message || 'Failed to import RBAC';
      setError(errorMessage);
      return { success: false, error: errorMessage };
    } finally {
      setImporting(false);
    }
  }, []);

  /**
   * Import global RBAC templates (SysAdmin only)
   */
  const importGlobalRbac = useCallback(async (
    data: RbacExport,
    mode: ImportMode = 'merge'
  ): Promise<{ success: boolean; result?: RbacImportResult; error?: string }> => {
    setImporting(true);
    setError(null);
    try {
      const response = await api.post(
        `/api/admin/rbac/global/import?mode=${mode}`,
        data
      );
      
      setLastImportResult(response.data);
      return { success: true, result: response.data };
    } catch (err: any) {
      const errorMessage = err.response?.data?.detail || err.message || 'Failed to import global RBAC';
      setError(errorMessage);
      return { success: false, error: errorMessage };
    } finally {
      setImporting(false);
    }
  }, []);

  /**
   * Download export as JSON file
   */
  const downloadExport = useCallback((data: RbacExport, filename?: string) => {
    const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = filename || `rbac-export-${data.scope.type}-${new Date().toISOString().split('T')[0]}.json`;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);
  }, []);

  /**
   * Parse uploaded JSON file
   */
  const parseImportFile = useCallback(async (file: File): Promise<{ success: boolean; data?: RbacExport; error?: string }> => {
    try {
      const text = await file.text();
      const data = JSON.parse(text) as RbacExport;
      
      // Basic validation
      if (!data.version) {
        return { success: false, error: 'Ungültiges Format: Fehlende Version' };
      }
      if (!data.scope) {
        return { success: false, error: 'Ungültiges Format: Fehlender Scope' };
      }
      if (!Array.isArray(data.roles)) {
        return { success: false, error: 'Ungültiges Format: Roles muss ein Array sein' };
      }
      if (!Array.isArray(data.accessRules)) {
        return { success: false, error: 'Ungültiges Format: AccessRules muss ein Array sein' };
      }
      
      return { success: true, data };
    } catch (err: any) {
      return { success: false, error: `Fehler beim Parsen: ${err.message}` };
    }
  }, []);

  /**
   * Clear state
   */
  const reset = useCallback(() => {
    setError(null);
    setLastExport(null);
    setLastImportResult(null);
  }, []);

  return {
    exporting,
    importing,
    error,
    lastExport,
    lastImportResult,
    exportMandateRbac,
    exportGlobalRbac,
    exportInstanceRbac,
    importMandateRbac,
    importGlobalRbac,
    downloadExport,
    parseImportFile,
    reset,
  };
}

export default useRbacExportImport;
