"""
ReaxFF control file generation utilities.

This module provides deterministic helpers for writing a default ReaxFF
``control`` input file from a canonical, aligned template.

Typical use cases include:
---

- generating a baseline ``control`` file for new run directories
- ensuring consistent spacing/alignment across generated inputs
- writing a known-good template for tutorials and examples
"""


from __future__ import annotations

from pathlib import Path
from typing import Union


CONTROL_TEMPLATE = """# General parameters
      1 iexx   
      1 iexy   
      1 iexz   
    7.5 vlbora
      1 icobo      0: use uncorrected bond orders for mol.nrs. in xmolout, fort.7 and fort.71 1: use corrected bond orders
      0 itrout     1: create diff_traj.xyz-output file with unfolded coordinates
      1 itrans     0: do not back-translate atoms  1: back translate atoms
      1 icentr     0: keep position   1: put centre of mass in centre periodic cell  2: put centre of mass at origin
      0 imetho     0: Normal MD-run 1: Energy minimisation 2:MD-energy minimisation
      1 igeofo     0:xyz-input geometry 1: Biograf input geometry 2: xmol-input geometry
 80.000 axis1      a (for non-periodical systems)
 80.000 axis2      b (for non-periodical systems)
 80.000 axis3      c (for non-periodical systems)
 0.0001 cutof2     BO-cutoff for valency angles and torsion angles
  0.300 cutof3     BO-cutoff for bond order for graphs
      7 icharg     Charges. 1:EEM 2:- 3: Shielded EEM 4: Full system EEM 5: Fixed (unit 26) 6: Fragment EEM
      1 ichaen     Charges. 1:include charge energy 0: Do not include charge energy
      1 iappen     1: Append fort.7 and fort.8
      0 isurpr     1: Surpress lots of output 2: Read in all geometries at the same time
     25 irecon     Frequency of reading control-file
      0 icheck     0: Normal run 1:Check first derivatives;2: Single run
      0 idebug     0: normal run 1: debug run
      3 ixmolo     0: only x,y,z-coordinates in xmolout  1: x,y,z + velocities + molnr. in xmolout 2:x,y,z+mol.nr.  3: x,y,z+mol.nr.+Estrain
# MD-parameters
      1 imdmet     MD-method. 1:NVT/Berendsen thermostat 2:do not use;3:NVE 4: NPT/Berendsen thermo/barostat
  0.250 tstep      MD-time step (fs)
0500.00 mdtemp     MD-temperature
0000.00 tincr      Increase/decrease temperature
      2 itdmet     0: T-damp atoms 1: Energy cons 2:System 3: Mols 4: Anderson 5: Mols+2 types of damping
  100.0 tdamp1     1st Berendsen/Anderson temperature damping constant (fs)
0000.00 mdpres     MD-pressure (MPa)
05000.0 pdamp1     Berendsen pressure damping constant (fs)
      0 inpt       0: Change all cell parameters in NPT-run  1: fixed x 2: fixed y 3: fixed z
0155000 nmdit      Number of MD-iterations
  00001 ichupd     Charge update frequency
    025 iout1      Output to unit 71 and unit 73
    100 iout2      Save coordinates
      0 ivels      1:Set vels and accels from moldyn.vel to zero
  00025 itrafr     Frequency of trarot-calls
      1 iout3      0: create moldyn.xxxx-files 1: do not create moldyn.xxxx-files
      1 iravel     1: Random initial velocities
 025000 iout6      Save velocity file
 000025 irten      Frequency of removal of rotational and translational energy
      0 npreit     Nr. of iterations in previous runs
   0.00 range      Range for back-translation of atoms
# MM-parameters
1.00000 endmm      End point criterium for MM energy minimisation
 -00001 imaxmo     <0 MD-based energy minimization >0 Steepest descent maximum movement (1/1D6 A) 0: Conjugate gradient
  00000 imaxit     Maximum number of iterations
    005 iout4      Frequency of structure output during minimisation
      0 iout5      1:Remove fort.57 and fort.58 files
1.00250 celopt     Cell parameter change
      0 icelo2     Change all cell parameters (0) or only x/y/z axis (1/2/3)
# FF-optimisation parameters
   0.25 parsca     Parameter optimization: parameter step scaling
 0.0100 parext     Parameter optimization: extrapolation
      0 icelop     0: No cell parameter optimisation 1:Cell parameter optimisation
      1 igeopt     0: Always use same start gemetries 1:Use latest geometries in optimisation
      0 iincop     heat increment optimisation 1: yes 0: no
25.0000 accerr     Accepted increase in error force field
#Outdated parameters 
      0 nreac      0: reactive; 1: non-reactive; 2: Place default atoms
      1 ibiola     0: output *.geo and *.bgf-files 1: surpress *.geo and *.bgf output files
      0 itfix      1:Keep temperature fixed at exactly tset
"""


def write_control_template(out_path: Union[str, Path] = "control") -> Path:
    """
    Write the default ReaxFF ``control`` file template to disk.

    This function writes a fully populated ReaxFF control-file template
    (general, MD, MM, FF-optimization, and outdated sections) to disk,
    preserving the exact spacing and alignment of the canonical template.

    Works on
    --------
    None — writes a ReaxFF ``control`` input file

    Parameters
    ----------
    out_path : str | pathlib.Path, optional
        Output file path to write (default: ``"control"``). Parent
        directories are created automatically if they do not exist.

    Returns
    -------
    pathlib.Path
        The resolved path of the written control file.

    Examples
    --------
    >>> from reaxkit.io.generators.control_generator import write_control_template
    >>> p = write_control_template("run_001/control")
    >>> p.name
    'control'
    """
    out_path = Path(out_path)
    out_path.parent.mkdir(parents=True, exist_ok=True)
    out_path.write_text(CONTROL_TEMPLATE, encoding="utf-8")
    return out_path
