import * as plugins from '../plugins.js';
import type * as servezoneInterfaces from '@serve.zone/interfaces';
import * as interfaces from '../../ts_interfaces/index.js';
import { appState } from './shared.js';
import { getActionContext } from './login.js';

export interface ICertificateState {
  certificates: interfaces.requests.ICertificateInfo[];
  summary: { total: number; valid: number; expiring: number; expired: number; failed: number; unknown: number };
  isLoading: boolean;
  error: string | null;
  lastUpdated: number;
}

export const certificateStatePart = await appState.getStatePart<ICertificateState>(
  'certificates',
  {
    certificates: [],
    summary: { total: 0, valid: 0, expiring: 0, expired: 0, failed: 0, unknown: 0 },
    isLoading: false,
    error: null,
    lastUpdated: 0,
  },
  'soft'
);

// Certificate Actions
// ============================================================================

export const fetchCertificateOverviewAction = certificateStatePart.createAction(async (statePartArg): Promise<ICertificateState> => {
  const context = getActionContext();
  const currentState = statePartArg.getState()!;
  if (!context.identity) return currentState;

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

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

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

export async function requestCertificateReprovision(domain: string, forceRenew?: boolean) {
  const context = getActionContext();
  const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
    interfaces.requests.IReq_ReprovisionCertificateDomain
  >('/typedrequest', 'reprovisionCertificateDomain');

  return request.fire({
    identity: context.identity!,
    domain,
    forceRenew,
  });
}

export const deleteCertificateAction = certificateStatePart.createAction<string>(
  async (statePartArg, domain, actionContext): Promise<ICertificateState> => {
    const context = getActionContext();
    const currentState = statePartArg.getState()!;

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

      await request.fire({
        identity: context.identity!,
        domain,
      });

      // Re-fetch overview after deletion
      return await actionContext!.dispatch(fetchCertificateOverviewAction, null);
    } catch (error: unknown) {
      return {
        ...currentState,
        error: error instanceof Error ? error.message : 'Failed to delete certificate',
      };
    }
  }
);

export const importCertificateAction = certificateStatePart.createAction<{
  id: string;
  domainName: string;
  created: number;
  validUntil: number;
  privateKey: string;
  publicKey: string;
  csr: string;
}>(
  async (statePartArg, cert, actionContext): Promise<ICertificateState> => {
    const context = getActionContext();
    const currentState = statePartArg.getState()!;

    try {
      const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
        servezoneInterfaces.requests.gateway.IReq_ImportCertificate
      >('/typedrequest', 'importCertificate');

      await request.fire({
        identity: context.identity!,
        cert,
      });

      // Re-fetch overview after import
      return await actionContext!.dispatch(fetchCertificateOverviewAction, null);
    } catch (error: unknown) {
      return {
        ...currentState,
        error: error instanceof Error ? error.message : 'Failed to import certificate',
      };
    }
  }
);

export async function fetchCertificateExport(domain: string) {
  const context = getActionContext();
  const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
    servezoneInterfaces.requests.gateway.IReq_ExportCertificate
  >('/typedrequest', 'exportCertificate');

  return request.fire({
    identity: context.identity!,
    domain,
  });
}

// ============================================================================
