import * as plugins from '../plugins.js';
import * as interfaces from '../../ts_interfaces/index.js';
import { appState } from './shared.js';
import { getActionContext } from './login.js';

// Target Profiles State
// ============================================================================

export interface ITargetProfilesState {
  profiles: interfaces.data.ITargetProfile[];
  isLoading: boolean;
  error: string | null;
  lastUpdated: number;
}

export const targetProfilesStatePart = await appState.getStatePart<ITargetProfilesState>(
  'targetProfiles',
  {
    profiles: [],
    isLoading: false,
    error: null,
    lastUpdated: 0,
  },
  'soft'
);

// ============================================================================
// Target Profiles Actions
// ============================================================================

export const fetchTargetProfilesAction = targetProfilesStatePart.createAction(
  async (statePartArg): Promise<ITargetProfilesState> => {
    const context = getActionContext();
    const currentState = statePartArg.getState()!;
    if (!context.identity) return currentState;

    try {
      const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
        interfaces.requests.IReq_GetTargetProfiles
      >('/typedrequest', 'getTargetProfiles');

      const response = await request.fire({ identity: context.identity });

      return {
        profiles: response.profiles,
        isLoading: false,
        error: null,
        lastUpdated: Date.now(),
      };
    } catch (error) {
      return {
        ...currentState,
        isLoading: false,
        error: error instanceof Error ? error.message : 'Failed to fetch target profiles',
      };
    }
  }
);

export const createTargetProfileAction = targetProfilesStatePart.createAction<{
  name: string;
  description?: string;
  domains?: string[];
  targets?: Array<{ ip: string; port: number }>;
  routeRefs?: string[];
  allowRoutesByClientSourceIp?: boolean;
}>(async (statePartArg, dataArg, actionContext): Promise<ITargetProfilesState> => {
  const context = getActionContext();
  try {
    const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
      interfaces.requests.IReq_CreateTargetProfile
    >('/typedrequest', 'createTargetProfile');
    const response = await request.fire({
      identity: context.identity!,
      name: dataArg.name,
      description: dataArg.description,
      domains: dataArg.domains,
      targets: dataArg.targets,
      routeRefs: dataArg.routeRefs,
      allowRoutesByClientSourceIp: dataArg.allowRoutesByClientSourceIp,
    });
    if (!response.success) {
      return {
        ...statePartArg.getState()!,
        error: response.message || 'Failed to create target profile',
      };
    }
    return await actionContext!.dispatch(fetchTargetProfilesAction, null);
  } catch (error: unknown) {
    return {
      ...statePartArg.getState()!,
      error: error instanceof Error ? error.message : 'Failed to create target profile',
    };
  }
});

export const updateTargetProfileAction = targetProfilesStatePart.createAction<{
  id: string;
  name?: string;
  description?: string;
  domains?: string[];
  targets?: Array<{ ip: string; port: number }>;
  routeRefs?: string[];
  allowRoutesByClientSourceIp?: boolean;
}>(async (statePartArg, dataArg, actionContext): Promise<ITargetProfilesState> => {
  const context = getActionContext();
  try {
    const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
      interfaces.requests.IReq_UpdateTargetProfile
    >('/typedrequest', 'updateTargetProfile');
    const response = await request.fire({
      identity: context.identity!,
      id: dataArg.id,
      name: dataArg.name,
      description: dataArg.description,
      domains: dataArg.domains,
      targets: dataArg.targets,
      routeRefs: dataArg.routeRefs,
      allowRoutesByClientSourceIp: dataArg.allowRoutesByClientSourceIp,
    });
    if (!response.success) {
      return {
        ...statePartArg.getState()!,
        error: response.message || 'Failed to update target profile',
      };
    }
    return await actionContext!.dispatch(fetchTargetProfilesAction, null);
  } catch (error: unknown) {
    return {
      ...statePartArg.getState()!,
      error: error instanceof Error ? error.message : 'Failed to update target profile',
    };
  }
});

export const deleteTargetProfileAction = targetProfilesStatePart.createAction<{
  id: string;
  force?: boolean;
}>(async (statePartArg, dataArg, actionContext): Promise<ITargetProfilesState> => {
  const context = getActionContext();
  try {
    const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
      interfaces.requests.IReq_DeleteTargetProfile
    >('/typedrequest', 'deleteTargetProfile');
    const response = await request.fire({
      identity: context.identity!,
      id: dataArg.id,
      force: dataArg.force,
    });
    if (!response.success) {
      return {
        ...statePartArg.getState()!,
        error: response.message || 'Failed to delete target profile',
      };
    }
    return await actionContext!.dispatch(fetchTargetProfilesAction, null);
  } catch (error: unknown) {
    return {
      ...statePartArg.getState()!,
      error: error instanceof Error ? error.message : 'Failed to delete target profile',
    };
  }
});

