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

// ============================================================================
// Source Profiles & Network Targets State
// ============================================================================

export interface IProfilesTargetsState {
  profiles: interfaces.data.ISourceProfile[];
  targets: interfaces.data.INetworkTarget[];
  isLoading: boolean;
  error: string | null;
  lastUpdated: number;
}

export const profilesTargetsStatePart = await appState.getStatePart<IProfilesTargetsState>(
  'profilesTargets',
  {
    profiles: [],
    targets: [],
    isLoading: false,
    error: null,
    lastUpdated: 0,
  },
  'soft'
);

// ============================================================================
// Source Profiles & Network Targets Actions
// ============================================================================

export const fetchProfilesAndTargetsAction = profilesTargetsStatePart.createAction(
  async (statePartArg): Promise<IProfilesTargetsState> => {
    const context = getActionContext();
    const currentState = statePartArg.getState()!;
    if (!context.identity) return currentState;

    try {
      const profilesRequest = new plugins.domtools.plugins.typedrequest.TypedRequest<
        interfaces.requests.IReq_GetSourceProfiles
      >('/typedrequest', 'getSourceProfiles');

      const targetsRequest = new plugins.domtools.plugins.typedrequest.TypedRequest<
        interfaces.requests.IReq_GetNetworkTargets
      >('/typedrequest', 'getNetworkTargets');

      const [profilesResponse, targetsResponse] = await Promise.all([
        profilesRequest.fire({ identity: context.identity }),
        targetsRequest.fire({ identity: context.identity }),
      ]);

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

export const createProfileAction = profilesTargetsStatePart.createAction<{
  name: string;
  description?: string;
  security: any;
  extendsProfiles?: string[];
}>(async (statePartArg, dataArg, actionContext): Promise<IProfilesTargetsState> => {
  const context = getActionContext();
  try {
    const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
      interfaces.requests.IReq_CreateSourceProfile
    >('/typedrequest', 'createSourceProfile');
    await request.fire({
      identity: context.identity!,
      name: dataArg.name,
      description: dataArg.description,
      security: dataArg.security,
      extendsProfiles: dataArg.extendsProfiles,
    });
    return await actionContext!.dispatch(fetchProfilesAndTargetsAction, null);
  } catch (error: unknown) {
    return {
      ...statePartArg.getState()!,
      error: error instanceof Error ? error.message : 'Failed to create profile',
    };
  }
});

export const updateProfileAction = profilesTargetsStatePart.createAction<{
  id: string;
  name?: string;
  description?: string;
  security?: any;
  extendsProfiles?: string[];
}>(async (statePartArg, dataArg, actionContext): Promise<IProfilesTargetsState> => {
  const context = getActionContext();
  try {
    const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
      interfaces.requests.IReq_UpdateSourceProfile
    >('/typedrequest', 'updateSourceProfile');
    await request.fire({
      identity: context.identity!,
      id: dataArg.id,
      name: dataArg.name,
      description: dataArg.description,
      security: dataArg.security,
      extendsProfiles: dataArg.extendsProfiles,
    });
    return await actionContext!.dispatch(fetchProfilesAndTargetsAction, null);
  } catch (error: unknown) {
    return {
      ...statePartArg.getState()!,
      error: error instanceof Error ? error.message : 'Failed to update profile',
    };
  }
});

export const deleteProfileAction = profilesTargetsStatePart.createAction<{
  id: string;
  force?: boolean;
}>(async (statePartArg, dataArg, actionContext): Promise<IProfilesTargetsState> => {
  const context = getActionContext();
  try {
    const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
      interfaces.requests.IReq_DeleteSourceProfile
    >('/typedrequest', 'deleteSourceProfile');
    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 profile',
      };
    }
    return await actionContext!.dispatch(fetchProfilesAndTargetsAction, null);
  } catch (error: unknown) {
    return {
      ...statePartArg.getState()!,
      error: error instanceof Error ? error.message : 'Failed to delete profile',
    };
  }
});

export const createTargetAction = profilesTargetsStatePart.createAction<{
  name: string;
  description?: string;
  host: string | string[];
  port: number;
}>(async (statePartArg, dataArg, actionContext): Promise<IProfilesTargetsState> => {
  const context = getActionContext();
  try {
    const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
      interfaces.requests.IReq_CreateNetworkTarget
    >('/typedrequest', 'createNetworkTarget');
    await request.fire({
      identity: context.identity!,
      name: dataArg.name,
      description: dataArg.description,
      host: dataArg.host,
      port: dataArg.port,
    });
    return await actionContext!.dispatch(fetchProfilesAndTargetsAction, null);
  } catch (error: unknown) {
    return {
      ...statePartArg.getState()!,
      error: error instanceof Error ? error.message : 'Failed to create target',
    };
  }
});

export const updateTargetAction = profilesTargetsStatePart.createAction<{
  id: string;
  name?: string;
  description?: string;
  host?: string | string[];
  port?: number;
}>(async (statePartArg, dataArg, actionContext): Promise<IProfilesTargetsState> => {
  const context = getActionContext();
  try {
    const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
      interfaces.requests.IReq_UpdateNetworkTarget
    >('/typedrequest', 'updateNetworkTarget');
    await request.fire({
      identity: context.identity!,
      id: dataArg.id,
      name: dataArg.name,
      description: dataArg.description,
      host: dataArg.host,
      port: dataArg.port,
    });
    return await actionContext!.dispatch(fetchProfilesAndTargetsAction, null);
  } catch (error: unknown) {
    return {
      ...statePartArg.getState()!,
      error: error instanceof Error ? error.message : 'Failed to update target',
    };
  }
});

export const deleteTargetAction = profilesTargetsStatePart.createAction<{
  id: string;
  force?: boolean;
}>(async (statePartArg, dataArg, actionContext): Promise<IProfilesTargetsState> => {
  const context = getActionContext();
  try {
    const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
      interfaces.requests.IReq_DeleteNetworkTarget
    >('/typedrequest', 'deleteNetworkTarget');
    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',
      };
    }
    return await actionContext!.dispatch(fetchProfilesAndTargetsAction, null);
  } catch (error: unknown) {
    return {
      ...statePartArg.getState()!,
      error: error instanceof Error ? error.message : 'Failed to delete target',
    };
  }
});

