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


// ============================================================================
// Email Domains State
// ============================================================================

export interface IEmailDomainsState {
  domains: interfaces.data.IEmailDomain[];
  settings: interfaces.data.IEmailServerSettings | null;
  isLoading: boolean;
  lastUpdated: number;
}

export const emailDomainsStatePart = await appState.getStatePart<IEmailDomainsState>(
  'emailDomains',
  {
    domains: [],
    settings: null,
    isLoading: false,
    lastUpdated: 0,
  },
  'soft',
);

export const fetchEmailDomainsAction = emailDomainsStatePart.createAction(
  async (statePartArg): Promise<IEmailDomainsState> => {
    const context = getActionContext();
    const currentState = statePartArg.getState()!;
    if (!context.identity) return currentState;

    try {
      const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
        interfaces.requests.IReq_GetEmailDomains
      >('/typedrequest', 'getEmailDomains');
      const settingsRequest = new plugins.domtools.plugins.typedrequest.TypedRequest<
        interfaces.requests.IReq_GetEmailServerSettings
      >('/typedrequest', 'getEmailServerSettings');
      const response = await request.fire({ identity: context.identity });
      const settingsResponse = await settingsRequest.fire({ identity: context.identity });
      return {
        ...currentState,
        domains: response.domains,
        settings: settingsResponse.settings,
        isLoading: false,
        lastUpdated: Date.now(),
      };
    } catch {
      return { ...currentState, isLoading: false };
    }
  },
);

export const createEmailDomainAction = emailDomainsStatePart.createAction<{
  linkedDomainId: string;
  subdomain?: string;
  dkimSelector?: string;
  dkimKeySize?: number;
  rotateKeys?: boolean;
  rotationIntervalDays?: number;
}>(async (statePartArg, args, actionContext) => {
  const context = getActionContext();
  const currentState = statePartArg.getState()!;
  try {
    const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
      interfaces.requests.IReq_CreateEmailDomain
    >('/typedrequest', 'createEmailDomain');
    await request.fire({ identity: context.identity!, ...args });
    return await actionContext!.dispatch(fetchEmailDomainsAction, null);
  } catch {
    return currentState;
  }
});

export const updateEmailServerSettingsAction = emailDomainsStatePart.createAction<
  interfaces.data.TEmailServerSettingsUpdate
>(async (statePartArg, settings, actionContext) => {
  const context = getActionContext();
  const currentState = statePartArg.getState()!;
  try {
    const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
      interfaces.requests.IReq_UpdateEmailServerSettings
    >('/typedrequest', 'updateEmailServerSettings');
    const response = await request.fire({ identity: context.identity!, settings });
    if (!response.success) {
      return currentState;
    }
    return await actionContext!.dispatch(fetchEmailDomainsAction, null);
  } catch {
    return currentState;
  }
});

export const deleteEmailDomainAction = emailDomainsStatePart.createAction<string>(
  async (statePartArg, id, actionContext) => {
    const context = getActionContext();
    const currentState = statePartArg.getState()!;
    try {
      const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
        interfaces.requests.IReq_DeleteEmailDomain
      >('/typedrequest', 'deleteEmailDomain');
      await request.fire({ identity: context.identity!, id });
      return await actionContext!.dispatch(fetchEmailDomainsAction, null);
    } catch {
      return currentState;
    }
  },
);

export const validateEmailDomainAction = emailDomainsStatePart.createAction<string>(
  async (statePartArg, id, actionContext) => {
    const context = getActionContext();
    const currentState = statePartArg.getState()!;
    try {
      const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
        interfaces.requests.IReq_ValidateEmailDomain
      >('/typedrequest', 'validateEmailDomain');
      await request.fire({ identity: context.identity!, id });
      return await actionContext!.dispatch(fetchEmailDomainsAction, null);
    } catch {
      return currentState;
    }
  },
);

export const provisionEmailDomainDnsAction = emailDomainsStatePart.createAction<string>(
  async (statePartArg, id, actionContext) => {
    const context = getActionContext();
    const currentState = statePartArg.getState()!;
    try {
      const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
        interfaces.requests.IReq_ProvisionEmailDomainDns
      >('/typedrequest', 'provisionEmailDomainDns');
      await request.fire({ identity: context.identity!, id });
      return await actionContext!.dispatch(fetchEmailDomainsAction, null);
    } catch {
      return currentState;
    }
  },
);

// ============================================================================
// Email Domain Standalone Functions
// ============================================================================

export async function fetchEmailDomainDnsRecords(id: string) {
  const context = getActionContext();
  const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
    interfaces.requests.IReq_GetEmailDomainDnsRecords
  >('/typedrequest', 'getEmailDomainDnsRecords');
  return request.fire({ identity: context.identity!, id });
}
