import { ApiRequestOptions } from '../hooks/useApi';

// ============================================================================
// TYPES & INTERFACES
// ============================================================================

export interface Automation {
    id: string;
    mandateId: string;
    featureInstanceId: string;
    label: string;
    template: string | object;
    placeholders: Record<string, string>;
    schedule: string;
    active: boolean;
    status?: string;
    lastExecution?: number;
    nextExecution?: number;
    executionLogs?: AutomationLog[];
    _createdAt?: number;
    _updatedAt?: number;
    _createdByUserName?: string;
    mandateName?: string;
    [key: string]: any;
}

export interface AutomationLog {
    id: string;
    timestamp: number;
    status: string;
    workflowId?: string;
    messages?: string[];
}

export interface AutomationTemplate {
    template: {
        overview?: string;
        tasks?: Array<{
            description?: string;
            objective?: string;
            [key: string]: any;
        }>;
        [key: string]: any;
    };
    parameters?: Record<string, any>;
}

export interface CreateAutomationRequest {
    label: string;
    template: string;
    placeholders?: Record<string, string>;
    schedule?: string;
    active?: boolean;
    mandateId?: string;
    featureInstanceId?: string;
}

export interface UpdateAutomationRequest {
    label?: string;
    template?: string;
    placeholders?: Record<string, string>;
    schedule?: string;
    active?: boolean;
}

export interface ExecuteAutomationResponse {
    id: string;
    status: string;
    workflowId?: string;
    [key: string]: any;
}

// Type for the request function passed to API functions
export type ApiRequestFunction = (options: ApiRequestOptions<any>) => Promise<any>;

// ============================================================================
// API REQUEST FUNCTIONS
// ============================================================================

/**
 * Fetch all automations for the current mandate
 * Endpoint: GET /api/automations
 */
export async function fetchAutomations(request: ApiRequestFunction): Promise<Automation[]> {
    console.log('📤 fetchAutomations: Making API request to /api/automations');
    
    try {
        const data = await request({
            url: '/api/automations',
            method: 'get'
        });
        
        console.log('📥 fetchAutomations: API response:', data);
        
        // Handle different response formats
        let automations: Automation[] = [];
        
        if (Array.isArray(data)) {
            automations = data;
        } else if (data && typeof data === 'object') {
            if (Array.isArray(data.automations)) {
                automations = data.automations;
            } else if (Array.isArray(data.items)) {
                automations = data.items;
            } else if (Array.isArray(data.data)) {
                automations = data.data;
            }
        }
        
        console.log(`✅ fetchAutomations: Returning ${automations.length} automations`);
        return automations;
    } catch (error) {
        console.error('❌ fetchAutomations: Error fetching automations:', error);
        throw error;
    }
}

/**
 * Fetch a single automation by ID
 * Endpoint: GET /api/automations/{automationId}
 */
export async function fetchAutomation(
    request: ApiRequestFunction,
    automationId: string
): Promise<Automation> {
    return await request({
        url: `/api/automations/${automationId}`,
        method: 'get'
    });
}

/**
 * Create a new automation
 * Endpoint: POST /api/automations
 */
export async function createAutomationApi(
    request: ApiRequestFunction,
    automationData: CreateAutomationRequest
): Promise<Automation> {
    return await request({
        url: '/api/automations',
        method: 'post',
        data: automationData
    });
}

/**
 * Update an existing automation
 * Endpoint: PUT /api/automations/{automationId}
 */
export async function updateAutomationApi(
    request: ApiRequestFunction,
    automationId: string,
    updateData: UpdateAutomationRequest
): Promise<Automation> {
    return await request({
        url: `/api/automations/${automationId}`,
        method: 'put',
        data: updateData
    });
}

/**
 * Delete an automation
 * Endpoint: DELETE /api/automations/{automationId}
 */
export async function deleteAutomationApi(
    request: ApiRequestFunction,
    automationId: string
): Promise<void> {
    await request({
        url: `/api/automations/${automationId}`,
        method: 'delete'
    });
}

/**
 * Execute an automation (test mode)
 * Endpoint: POST /api/automations/{automationId}/execute
 */
export async function executeAutomationApi(
    request: ApiRequestFunction,
    automationId: string
): Promise<ExecuteAutomationResponse> {
    return await request({
        url: `/api/automations/${automationId}/execute`,
        method: 'post'
    });
}

/**
 * Fetch automation templates
 * Endpoint: GET /api/automations/templates
 */
export async function fetchAutomationTemplates(
    request: ApiRequestFunction
): Promise<AutomationTemplate[]> {
    const data = await request({
        url: '/api/automations/templates',
        method: 'get'
    });
    
    if (Array.isArray(data)) {
        return data;
    }
    
    if (data && typeof data === 'object') {
        if (Array.isArray(data.sets)) {
            return data.sets;
        }
        if (Array.isArray(data.templates)) {
            return data.templates;
        }
    }
    
    return [];
}

/**
 * Fetch automation attributes for dynamic form generation
 * Endpoint: GET /api/attributes/AutomationDefinition
 */
export async function fetchAutomationAttributes(
    request: ApiRequestFunction
): Promise<any[]> {
    const data = await request({
        url: '/api/attributes/AutomationDefinition',
        method: 'get'
    });
    
    if (data?.attributes && Array.isArray(data.attributes)) {
        return data.attributes;
    }
    
    if (Array.isArray(data)) {
        return data;
    }
    
    return [];
}
