{ lib, pkgs, cfg, models, allPhones }:

let
  hasTrunk = cfg.sipTrunks != {};

  # Import provisioning templates for models that support it.
  # Each template exports: desktopSize, thumbnailSize, mkFiles
  templates = lib.mapAttrs (modelName: _:
    import ./templates/${modelName}.nix { inherit lib; }
  ) (lib.filterAttrs (_: m: m.hasProvisioning) models);

  # Page extensions for the intercom button auto-dial
  pageExtension =
    let pages = lib.attrNames (lib.filterAttrs (_: e: e.mode == "page") cfg.extensions);
    in if pages != [] then lib.head pages else null;

  hasIntercomButton = cfg.intercomPrefix != null && pageExtension != null;

  # Collect all internal extension numbers to generate exact-match patterns.
  # This tells the phone "this number is complete" so it dials immediately
  # rather than waiting for the timeout or firing on the first digit.
  allExtensions = lib.unique (
    lib.mapAttrsToList (_: p: p.extension) cfg.sharedPhones
    ++ lib.mapAttrsToList (_: p: p.extension) cfg.persons
  );

  # Star extensions: intercom prefix + each extension, plus custom extensions.
  allStarExtensions =
    (lib.optionals (cfg.intercomPrefix != null)
      (map (ext: "${cfg.intercomPrefix}${ext}") allExtensions))
    ++ lib.attrNames cfg.extensions
    ++ lib.optional (cfg.sharedMailbox != null) cfg.sharedMailbox.checkExtension;

  backgroundEntries = import ./backgrounds.nix { inherit lib pkgs cfg templates allPhones; };

in
pkgs.linkFarm "voip-tftp-root" (
  lib.concatLists (lib.mapAttrsToList (key: phone:
    let m = models.${phone.model}; in
    lib.optionals m.hasProvisioning (
      let
        t                 = templates.${phone.model};
        familyLineEnabled = hasTrunk && phone.personKey != null && phone.sharedLine;
        intercomLineIndex = if familyLineEnabled then 3 else 2;

        # BLF targets: all persons except the one owning this phone
        blfPersons = lib.filter (p: p.extension != phone.extension)
          (lib.mapAttrsToList (_: person: {
            inherit (person) extension displayName;
          }) cfg.persons);

        files = t.mkFiles ({
          mac           = key;
          inherit (phone) label password displayName extension;
          inherit blfPersons;
          serverAddress = cfg.serverAddress;
          ntpServer     = cfg.ntpServer;
          sipPort       = cfg.sipPort;
          directoryPort = cfg.directoryPort;
          inherit allExtensions allStarExtensions hasTrunk hasIntercomButton pageExtension intercomLineIndex;
          voicemailCheckExtension  = cfg.voicemailCheckExtension;
          familyLineCheckExtension = if cfg.sharedMailbox != null then cfg.sharedMailbox.checkExtension else cfg.voicemailCheckExtension;
        } // lib.optionalAttrs (cfg.intercomPrefix != null) {
          intercomEnabled  = true;
          intercomPassword = phone.password;
        } // lib.optionalAttrs familyLineEnabled {
          inherit familyLineEnabled;
          familyLineLabel    =
            if cfg.sharedMailbox != null
              then cfg.sharedMailbox.displayName
              else "Familie";
          familyLinePassword = phone.password;
        });
      in
        map (f: { inherit (f) name; path = pkgs.writeText f.name f.content; }) files
    )
  ) allPhones)
  ++ backgroundEntries
)
