import { createSlice, createAsyncThunk, PayloadAction } from '@reduxjs/toolkit';
import type { RiskRule } from '@/domain/entities/risk-rule';
import { apiClient } from '@/infrastructure/api/api-client';

interface RiskRulesState {
  rules: RiskRule[];
  loading: boolean;
  error: string | null;
  selectedRuleId: string | null;
}

const initialState: RiskRulesState = {
  rules: [],
  loading: false,
  error: null,
  selectedRuleId: null,
};

export const fetchRiskRules = createAsyncThunk(
  'riskRules/fetchAll',
  async (params?: Record<string, string>) => {
    const query = params ? '?' + new URLSearchParams(params).toString() : '';
    return apiClient<RiskRule[]>(`/api/v1/agent/risk-rules${query}`);
  },
);

export const addRiskRule = createAsyncThunk(
  'riskRules/add',
  async (rule: Omit<RiskRule, 'id' | 'createdAt' | 'updatedAt'>) => {
    return apiClient<RiskRule>('/api/v1/agent/risk-rules', {
      method: 'POST',
      body: rule,
    });
  },
);

export const editRiskRule = createAsyncThunk(
  'riskRules/edit',
  async ({ id, data }: { id: string; data: Partial<RiskRule> }) => {
    return apiClient<RiskRule>(`/api/v1/agent/risk-rules/${id}`, {
      method: 'PUT',
      body: data,
    });
  },
);

export const removeRiskRule = createAsyncThunk(
  'riskRules/remove',
  async (id: string) => {
    await apiClient(`/api/v1/agent/risk-rules/${id}`, {
      method: 'DELETE',
    });
    return id;
  },
);

export const riskRulesSlice = createSlice({
  name: 'riskRules',
  initialState,
  reducers: {
    selectRule: (state, action: PayloadAction<string | null>) => {
      state.selectedRuleId = action.payload;
    },
    clearError: (state) => {
      state.error = null;
    },
    addRule: (state, action: PayloadAction<RiskRule>) => {
      state.rules.push(action.payload);
    },
    removeRule: (state, action: PayloadAction<string>) => {
      state.rules = state.rules.filter((r) => r.id !== action.payload);
    },
    updateRule: (state, action: PayloadAction<{ id: string; changes: Partial<RiskRule> }>) => {
      const rule = state.rules.find((r) => r.id === action.payload.id);
      if (rule) {
        Object.assign(rule, action.payload.changes);
      }
    },
  },
  extraReducers: (builder) => {
    builder
      .addCase(fetchRiskRules.pending, (state) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(fetchRiskRules.fulfilled, (state, action) => {
        state.loading = false;
        state.rules = action.payload;
      })
      .addCase(fetchRiskRules.rejected, (state, action) => {
        state.loading = false;
        state.error = action.error.message ?? 'Failed to fetch risk rules';
      })
      .addCase(addRiskRule.fulfilled, (state, action) => {
        state.rules.push(action.payload);
      })
      .addCase(editRiskRule.fulfilled, (state, action) => {
        const index = state.rules.findIndex((r) => r.id === action.payload.id);
        if (index !== -1) {
          state.rules[index] = action.payload;
        }
      })
      .addCase(removeRiskRule.fulfilled, (state, action) => {
        state.rules = state.rules.filter((r) => r.id !== action.payload);
      });
  },
});

export const riskRulesActions = riskRulesSlice.actions;
