#!/usr/bin/env python3
"""
fill_application_template.py
Fills the Full Updated Application Word template with driver data.
Called by PHP: python fill_application_template.py <json_data_file> <output_path>

Produces a .docx file that matches the EXACT original format with data filled in.
"""
import sys
import json
import os
from copy import deepcopy
from docx import Document
from docx.shared import Pt, Inches
from docx.oxml.ns import qn

TEMPLATE_PATH = os.path.join(os.path.dirname(__file__), '..', '..', '..', 'NEWDOCS_4DOCS', 'Full Updated Application March 2024.docx')

def add_value_to_paragraph(para, value, bold=False, size=Pt(10)):
    """Append a value run to a paragraph after the label."""
    if not value:
        return
    run = para.add_run('  ' + str(value))
    run.font.size = size
    run.font.bold = bold
    run.font.color.rgb = None  # inherit

def fill_table_cell(table, row, col, value):
    """Fill a specific table cell with a value."""
    try:
        if row < len(table.rows) and col < len(table.rows[row].cells):
            cell = table.rows[row].cells[col]
            # Don't overwrite if cell already has label text
            existing = cell.text.strip()
            if existing and len(existing) > 3:
                # Cell has label text, append value
                if cell.paragraphs:
                    run = cell.paragraphs[-1].add_run('  ' + str(value))
                    run.font.size = Pt(9)
            else:
                # Empty cell, set value
                if cell.paragraphs:
                    cell.paragraphs[0].text = str(value)
                    for run in cell.paragraphs[0].runs:
                        run.font.size = Pt(9)
    except (IndexError, AttributeError):
        pass

def fill_template(data, output_path):
    """Fill the Word template with application data."""
    doc = Document(TEMPLATE_PATH)

    v = lambda key, default='': str(data.get(key, default) or default)

    # =============================================================
    # FIRST 4 PAGES - Personal Info, DL/CDL, Addresses, Background
    # =============================================================

    # --- Personal Info (paragraphs 27-29) ---
    if len(doc.paragraphs) > 29:
        add_value_to_paragraph(doc.paragraphs[27], v('name'))           # First Name
        add_value_to_paragraph(doc.paragraphs[28], v('middle_initial')) # Middle Initial
        add_value_to_paragraph(doc.paragraphs[29], v('date_of_birth')) # Birth date

    # --- DL & CDL (paragraphs 31-43) ---
    if len(doc.paragraphs) > 43:
        add_value_to_paragraph(doc.paragraphs[31], v('dl_number'))          # DL #
        add_value_to_paragraph(doc.paragraphs[32], v('cdl_holder'))         # CDL Holder
        add_value_to_paragraph(doc.paragraphs[33], v('cdl_class'))          # CDL Endorsement/Class
        add_value_to_paragraph(doc.paragraphs[43], v('dl_state'))           # State

    # CDL Endorsements - build string
    endorsements = []
    if data.get('hazmat'): endorsements.append('Hazmat (H)')
    if data.get('tankers'): endorsements.append('Tankers (N)')
    if data.get('doubles'): endorsements.append('Doubles/Triples (T)')
    if data.get('passenger'): endorsements.append('Passenger (P)')
    if endorsements and len(doc.paragraphs) > 33:
        add_value_to_paragraph(doc.paragraphs[33], ' - ' + ', '.join(endorsements))

    # --- Current Address (paragraphs 46-49) ---
    if len(doc.paragraphs) > 86:
        add_value_to_paragraph(doc.paragraphs[47], v('current_address'))    # Street Address
        add_value_to_paragraph(doc.paragraphs[48], v('current_city', v('city')))  # City
        add_value_to_paragraph(doc.paragraphs[49], v('county'))             # County
        add_value_to_paragraph(doc.paragraphs[86], v('current_zip', v('zip')))  # Zip

    # State + duration for current address (paragraphs 66-67)
    if len(doc.paragraphs) > 67:
        add_value_to_paragraph(doc.paragraphs[66], v('current_state', v('state')))
        add_value_to_paragraph(doc.paragraphs[67], v('address_duration'))

    # --- Previous Address 1 (paragraphs 50-53) ---
    for addr_num in [1, 2, 3]:
        base_para = {1: 51, 2: 55, 3: 59}[addr_num]
        if len(doc.paragraphs) > base_para + 2:
            add_value_to_paragraph(doc.paragraphs[base_para], v(f'prev_address_{addr_num}'))
            add_value_to_paragraph(doc.paragraphs[base_para + 1], v(f'prev_city_{addr_num}'))
            add_value_to_paragraph(doc.paragraphs[base_para + 2], v(f'prev_county_{addr_num}'))

    # --- Background Questions - Table 3 (14 rows x 6 cols) ---
    if len(doc.tables) > 3:
        t3 = doc.tables[3]
        # Row 0: empty (merged header)
        # Row 1: license suspended/revoked - answer in col 5
        fill_table_cell(t3, 1, 5, v('license_suspended_revoked', 'No'))
        # Row 2: empty
        # Row 3: stopped while intoxicated - answer in col 5
        fill_table_cell(t3, 3, 5, v('stopped_intoxicated', 'No'))
        # Row 5: used illegal drugs - answer in col 5
        fill_table_cell(t3, 5, 5, v('used_illegal_drugs', 'No'))
        # Row 8: convicted for drugs - answer in col 5
        fill_table_cell(t3, 8, 5, v('drug_conviction', 'No'))
        # Row 9: comments
        fill_table_cell(t3, 9, 1, v('drug_conviction_details'))
        # Row 10: traffic convictions
        fill_table_cell(t3, 10, 5, v('moving_violations', '0'))
        # Row 12: criminal conviction
        fill_table_cell(t3, 12, 5, v('criminal_pending', 'No'))

    # --- Other State Licenses - Table 4 (6 rows x 7 cols) ---
    if len(doc.tables) > 4:
        t4 = doc.tables[4]
        for n in range(1, 4):
            row_idx = n + 1  # rows 2,3,4
            fill_table_cell(t4, row_idx, 0, v(f'other_license_{n}_state'))
            fill_table_cell(t4, row_idx, 2, v(f'other_license_{n}_type'))
            fill_table_cell(t4, row_idx, 4, v(f'other_license_{n}_number'))

    # --- Driving Experience - Table 5 (7 rows x 9 cols) ---
    if len(doc.tables) > 5:
        t5 = doc.tables[5]
        equip_map = {
            3: 'straight_truck',
            4: 'tractor_trailer',
            5: 'tractor_two_trailers',
            6: 'other_equipment'
        }
        for row_idx, key in equip_map.items():
            fill_table_cell(t5, row_idx, 2, v(f'exp_{key}_type'))
            fill_table_cell(t5, row_idx, 3, v(f'exp_{key}_from'))
            fill_table_cell(t5, row_idx, 5, v(f'exp_{key}_to'))
            fill_table_cell(t5, row_idx, 6, v(f'exp_{key}_miles'))

    # --- Accidents Table - Table 6 (6 rows x 7 cols) ---
    if len(doc.tables) > 6:
        t6 = doc.tables[6]
        for n in range(1, 6):
            row_idx = n + 2  # data rows start at row 3
            if row_idx < len(t6.rows):
                fill_table_cell(t6, row_idx, 0, v(f'incident_{n}_date'))
                fill_table_cell(t6, row_idx, 1, v(f'incident_{n}_vehicle'))
                fill_table_cell(t6, row_idx, 3, v(f'incident_{n}_nature'))
                fill_table_cell(t6, row_idx, 4, v(f'incident_{n}_preventable'))
                fill_table_cell(t6, row_idx, 5, v(f'incident_{n}_fatalities'))
                fill_table_cell(t6, row_idx, 6, v(f'incident_{n}_injuries'))

    # --- Work History - 4 employers (paragraphs 119-188) ---
    employer_starts = {
        1: {'name': 121, 'contact': 122, 'street': 123, 'address': 124,
            'city': 125, 'phone': 126, 'position': 127, 'reason': 128},
        2: {'name': 142, 'contact': 143, 'street': 144, 'address': 145,
            'city': 146, 'phone': 147, 'position': 148, 'reason': 149},
        3: {'name': 158, 'contact': 159, 'street': 160, 'address': 161,
            'city': 162, 'phone': 163, 'position': 164, 'reason': 165},
        4: {'name': 179, 'contact': 180, 'street': 181, 'address': 182,
            'city': 183, 'phone': 185, 'position': 186, 'reason': 187}
    }

    for emp_num, fields in employer_starts.items():
        prefix = f'employer_{emp_num}_'
        for field_key, para_idx in fields.items():
            if para_idx < len(doc.paragraphs):
                val = v(prefix + field_key) if field_key != 'contact' else v(prefix + 'contact')
                if val:
                    add_value_to_paragraph(doc.paragraphs[para_idx], val)

    # --- Education - Tables 7-10 (HS, College, Graduate, Trade) ---
    edu_map = {
        7: 'highschool',
        8: 'college',
        9: 'graduate',
        10: 'trade'
    }
    for table_idx, key in edu_map.items():
        if table_idx < len(doc.tables):
            t = doc.tables[table_idx]
            if len(t.rows) > 1:
                fill_table_cell(t, 1, 0, v(f'edu_{key}_name'))
                fill_table_cell(t, 1, 2, v(f'edu_{key}_graduated'))
                fill_table_cell(t, 1, 3, v(f'edu_{key}_degree'))
                fill_table_cell(t, 1, 4, v(f'edu_{key}_major'))

    # --- Military Service - Table 11 ---
    if len(doc.tables) > 11:
        t11 = doc.tables[11]
        if len(t11.rows) > 1:
            fill_table_cell(t11, 1, 0, v('military_branch'))
            fill_table_cell(t11, 1, 2, v('military_date_from'))
            fill_table_cell(t11, 1, 4, v('military_date_to'))

    # --- Signature paragraph (208) ---
    if len(doc.paragraphs) > 208:
        p208 = doc.paragraphs[208]
        add_value_to_paragraph(p208, v('name') + '    Date: ' + v('full_app_date', v('signature_date', '')))

    # =============================================================
    # ADDITIONAL PAGES
    # =============================================================

    # --- On-Duty Hours Table (Table 54) ---
    if len(doc.tables) > 54:
        t54 = doc.tables[54]
        for d in range(1, 8):
            fill_table_cell(t54, 2, d, v(f'onduty_day_{d}', '0'))
        # Total
        total = sum(float(data.get(f'onduty_day_{d}', 0) or 0) for d in range(1, 8))
        fill_table_cell(t54, 2, 8, str(total))

    # --- Various yes/no and name fields in later pages ---
    # These are in the paragraph stream - find by content matching
    for i, para in enumerate(doc.paragraphs):
        text = para.text.strip()

        # Driver Name fields (multiple places)
        if text == 'Driver Name (Print)' or text.startswith('Driver Name (Print)'):
            add_value_to_paragraph(para, v('name'))
        elif text.startswith('Social Security Number') and i > 300:
            add_value_to_paragraph(para, 'XXX-XX-' + v('onduty_ssn_last4', 'XXXX'))
        elif text.startswith("Driver's Signature") and not para.text.strip().endswith('Date'):
            add_value_to_paragraph(para, v('name') + ' (digitally signed)')

        # Company Name fields (leave for company to fill)
        # Employee Name in specific forms
        if "Employee's Name" in text and len(text) < 30:
            add_value_to_paragraph(para, v('name'))
        if "Company Name:" in text and len(text) < 25:
            add_value_to_paragraph(para, 'SH Logistics, LLC dba SH Transport')

        # Bank info section
        if text == 'Bank' and i > 500:
            add_value_to_paragraph(para, v('bank_name'))
        if 'Routing Number' in text and 'Account' in text:
            routing = v('bank_routing')
            account = v('bank_account')
            if routing or account:
                add_value_to_paragraph(para, f"R: {routing}  A: {account}")

    # =============================================================
    # Save the filled document
    # =============================================================
    doc.save(output_path)
    return output_path


if __name__ == '__main__':
    if len(sys.argv) < 3:
        print(json.dumps({'error': 'Usage: fill_application_template.py <json_file> <output_path>'}))
        sys.exit(1)

    json_file = sys.argv[1]
    output_path = sys.argv[2]

    try:
        with open(json_file, 'r', encoding='utf-8') as f:
            data = json.load(f)

        result = fill_template(data, output_path)
        print(json.dumps({'success': True, 'path': result}))
    except Exception as e:
        print(json.dumps({'error': str(e)}))
        sys.exit(1)
