import { type FileCardType } from '@material-hu/components/design-system/FileCard/types';

import { type TCustomFunction } from 'src/utils/i18n';

import {
  CertificateAlignment,
  CertificateColor,
  CertificateType,
} from '../constants';
import {
  type CertificateFileAsset,
  type LearningCertificateDTO,
} from '../types';

import { CERTIFICATE_MAX_LOGOS, CERTIFICATE_MAX_SIGNATURES } from './constants';
import {
  type CertificateCreateFormValues,
  type LogoSlot,
  type SignatureSlot,
} from './types';
import {
  convertFieldTokensToLocalized,
  joinSignaturesWithAssets,
} from './utils';

/** Typed accessor functions for all certificate form field names. */
export const certificateCreateFields = {
  type: (): 'type' => 'type',
  name: (): 'name' => 'name',
  title: (): 'title' => 'title',
  subtitle: (): 'subtitle' => 'subtitle',
  description: (): 'description' => 'description',
  color: (): 'color' => 'color',
  alignment: (): 'alignment' => 'alignment',
  certificateSignaturesEnabled: (): 'certificateSignaturesEnabled' =>
    'certificateSignaturesEnabled',
  certificateLogosEnabled: (): 'certificateLogosEnabled' =>
    'certificateLogosEnabled',
  signatureSlots: (): 'signatureSlots' => 'signatureSlots',
  logoSlots: (): 'logoSlots' => 'logoSlots',
  certificateCustomBackgroundFile: (): 'certificateCustomBackgroundFile' =>
    'certificateCustomBackgroundFile',
} as const;

export const emptySignatureSlot = (): SignatureSlot => ({
  id: crypto.randomUUID(),
  file: [],
  signerName: '',
  signerTitle: '',
});

export const emptyLogoSlot = (): LogoSlot => ({
  id: crypto.randomUUID(),
  file: [],
});

const certificateCreateBasicInformationDefaultKeys = {
  title: 'common.certificate',
  subtitle: 'settings.certificates.create_flow.defaults.subtitle',
  description: 'settings.certificates.create_flow.defaults.description',
};

/**
 * Rebuilds a `FileCardType` from a persisted certificate asset so the design
 * uploaders re-render the existing image and keep its `fileAsset.id` available
 * for the next PATCH payload.
 */
const certificateFileAssetToFileCard = (
  asset: CertificateFileAsset,
): FileCardType => ({
  status: 'success',
  fileAsset: {
    id: asset.id,
    url: asset.url,
    createdAt: '',
    updatedAt: '',
    externalReference: null,
    key: '',
    name: '',
    size: '',
    contentType: '',
    width: null,
    height: null,
    thumbnailUrl: null,
  },
});

/** Pads a slot list with empty slots so it always has `max` entries. */
const padSlots = <Slot>(
  slots: Slot[],
  max: number,
  makeEmpty: () => Slot,
): Slot[] => {
  const padding = Array.from(
    { length: Math.max(0, max - slots.length) },
    makeEmpty,
  );
  return [...slots.slice(0, max), ...padding];
};

const buildSignatureSlots = (dto: LearningCertificateDTO): SignatureSlot[] => {
  const slots = joinSignaturesWithAssets(
    dto.signatures,
    dto.signaturesFileAssets,
  ).map(({ signature, asset }) => ({
    id: crypto.randomUUID(),
    file: asset ? [certificateFileAssetToFileCard(asset)] : [],
    signerName: signature.signerName ?? '',
    signerTitle: signature.signerTitle ?? '',
  }));
  return padSlots(slots, CERTIFICATE_MAX_SIGNATURES, emptySignatureSlot);
};

const buildLogoSlots = (dto: LearningCertificateDTO): LogoSlot[] => {
  const slots = (dto.logoFileAssets ?? []).map(asset => ({
    id: crypto.randomUUID(),
    file: [certificateFileAssetToFileCard(asset)],
  }));
  return padSlots(slots, CERTIFICATE_MAX_LOGOS, emptyLogoSlot);
};

const buildCustomBackgroundFile = (
  dto: LearningCertificateDTO,
): FileCardType[] => {
  if (dto.type !== CertificateType.CUSTOM_BACKGROUND) return [];
  if (!dto.pictureId || !dto.pictureUrl) return [];
  return [
    certificateFileAssetToFileCard({ id: dto.pictureId, url: dto.pictureUrl }),
  ];
};

/**
 * Maps a persisted certificate DTO back into the wizard form values, the
 * inverse of `formatCreateRequest` + `formatDesignUpdateRequest`. Used to
 * preload the shared wizard in edit mode.
 */
export const getCertificateEditValues = (
  dto: LearningCertificateDTO,
  t: TCustomFunction,
): CertificateCreateFormValues => ({
  type: dto.type,
  name: dto.name,
  title: dto.title,
  subtitle: dto.subtitle ? convertFieldTokensToLocalized(dto.subtitle, t) : '',
  description: dto.description
    ? convertFieldTokensToLocalized(dto.description, t)
    : '',
  color: dto.color ?? CertificateColor.LIGHT_BLUE,
  alignment: dto.alignment,
  certificateSignaturesEnabled: Boolean(dto.signatures?.length),
  certificateLogosEnabled: Boolean(dto.logoFileAssets?.length),
  signatureSlots: buildSignatureSlots(dto),
  logoSlots: buildLogoSlots(dto),
  certificateCustomBackgroundFile: buildCustomBackgroundFile(dto),
});

export const getCertificateCreateDefaultValues = (
  t: TCustomFunction,
): CertificateCreateFormValues => ({
  type: CertificateType.CLASSIC,
  name: '',
  title: t(certificateCreateBasicInformationDefaultKeys.title),
  subtitle: t(certificateCreateBasicInformationDefaultKeys.subtitle),
  description: t(certificateCreateBasicInformationDefaultKeys.description),
  color: CertificateColor.LIGHT_BLUE,
  alignment: CertificateAlignment.CENTER,
  certificateSignaturesEnabled: false,
  certificateLogosEnabled: false,
  signatureSlots: [
    emptySignatureSlot(),
    emptySignatureSlot(),
    emptySignatureSlot(),
  ],
  logoSlots: [emptyLogoSlot(), emptyLogoSlot()],
  certificateCustomBackgroundFile: [],
});
