from pathlib import Path

from reportlab.lib import colors
from reportlab.lib.enums import TA_CENTER
from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import ParagraphStyle, getSampleStyleSheet
from reportlab.lib.units import mm
from reportlab.platypus import (
    Image,
    KeepTogether,
    ListFlowable,
    ListItem,
    PageBreak,
    Paragraph,
    SimpleDocTemplate,
    Spacer,
    Table,
    TableStyle,
)


ROOT = Path(__file__).resolve().parents[1]
OUTPUT_DIR = ROOT / "output" / "pdf"
OUTPUT_PDF = OUTPUT_DIR / "fleet_management_user_manual.pdf"
LOGO = ROOT / "uploads" / "company" / "company_logo_1779194635.png"
SCREENSHOT_DIR = ROOT / "docs" / "manual_screenshots"


PRIMARY = colors.HexColor("#15324A")
ACCENT = colors.HexColor("#287C76")
MUTED = colors.HexColor("#667085")
LIGHT = colors.HexColor("#EFF4F7")
RULE = colors.HexColor("#D6DEE6")


def bullet_items(items, style):
    rows = [["-", Paragraph(item, style)] for item in items]
    table = Table(rows, colWidths=[5 * mm, 148 * mm], hAlign="LEFT")
    table.setStyle(
        TableStyle(
            [
                ("FONTNAME", (0, 0), (0, -1), "Helvetica"),
                ("FONTSIZE", (0, 0), (0, -1), 8),
                ("TEXTCOLOR", (0, 0), (0, -1), ACCENT),
                ("VALIGN", (0, 0), (-1, -1), "TOP"),
                ("LEFTPADDING", (0, 0), (-1, -1), 0),
                ("RIGHTPADDING", (0, 0), (-1, -1), 2),
                ("TOPPADDING", (0, 0), (-1, -1), 0),
                ("BOTTOMPADDING", (0, 0), (-1, -1), 1),
            ]
        )
    )
    return table


def numbered_items(items, style):
    return ListFlowable(
        [ListItem(Paragraph(item, style), leftIndent=0) for item in items],
        bulletType="1",
        leftIndent=18,
        bulletFontSize=8,
    )


def section(title, styles):
    return [
        Spacer(1, 5 * mm),
        Paragraph(title, styles["SectionTitle"]),
        Spacer(1, 2 * mm),
    ]


def screenshot_block(filename, caption, styles):
    path = SCREENSHOT_DIR / filename
    if not path.exists():
        return []
    img = Image(str(path))
    max_width = 158 * mm
    max_height = 98 * mm
    scale = min(max_width / img.imageWidth, max_height / img.imageHeight)
    img.drawWidth = img.imageWidth * scale
    img.drawHeight = img.imageHeight * scale
    return [
        Spacer(1, 3 * mm),
        img,
        Paragraph(caption, styles["Caption"]),
        Spacer(1, 3 * mm),
    ]


def subsection(title, styles):
    return [
        Spacer(1, 3 * mm),
        Paragraph(title, styles["SubsectionTitle"]),
        Spacer(1, 1 * mm),
    ]


def module_block(title, purpose, common_tasks, good_practice, styles):
    return KeepTogether(
        [
            Paragraph(title, styles["SubsectionTitle"]),
            Paragraph(purpose, styles["Body"]),
            Paragraph("Common tasks", styles["SmallLabel"]),
            bullet_items(common_tasks, styles["Body"]),
            Paragraph("Good practice", styles["SmallLabel"]),
            Paragraph(good_practice, styles["Body"]),
            Spacer(1, 2 * mm),
        ]
    )


def workflow_table(rows, col_widths, styles):
    data = [[Paragraph(cell, styles["TableHeader"]) for cell in rows[0]]]
    for row in rows[1:]:
        data.append([Paragraph(str(cell), styles["TableCell"]) for cell in row])
    table = Table(data, colWidths=col_widths, hAlign="LEFT", repeatRows=1)
    table.setStyle(
        TableStyle(
            [
                ("BACKGROUND", (0, 0), (-1, 0), PRIMARY),
                ("TEXTCOLOR", (0, 0), (-1, 0), colors.white),
                ("FONTNAME", (0, 0), (-1, 0), "Helvetica-Bold"),
                ("FONTSIZE", (0, 0), (-1, -1), 8),
                ("GRID", (0, 0), (-1, -1), 0.35, RULE),
                ("ROWBACKGROUNDS", (0, 1), (-1, -1), [colors.white, LIGHT]),
                ("VALIGN", (0, 0), (-1, -1), "TOP"),
                ("LEFTPADDING", (0, 0), (-1, -1), 5),
                ("RIGHTPADDING", (0, 0), (-1, -1), 5),
                ("TOPPADDING", (0, 0), (-1, -1), 5),
                ("BOTTOMPADDING", (0, 0), (-1, -1), 5),
            ]
        )
    )
    return table


def add_page_number(canvas, doc):
    canvas.saveState()
    canvas.setStrokeColor(RULE)
    canvas.setLineWidth(0.5)
    canvas.line(doc.leftMargin, 14 * mm, A4[0] - doc.rightMargin, 14 * mm)
    canvas.setFont("Helvetica", 8)
    canvas.setFillColor(MUTED)
    canvas.drawString(doc.leftMargin, 9 * mm, "Fleet Management System User Manual")
    canvas.drawRightString(A4[0] - doc.rightMargin, 9 * mm, f"Page {doc.page}")
    canvas.restoreState()


def build_pdf():
    OUTPUT_DIR.mkdir(parents=True, exist_ok=True)

    doc = SimpleDocTemplate(
        str(OUTPUT_PDF),
        pagesize=A4,
        rightMargin=18 * mm,
        leftMargin=18 * mm,
        topMargin=18 * mm,
        bottomMargin=20 * mm,
        title="Fleet Management System User Manual",
        author="Fleet Management System",
    )

    base = getSampleStyleSheet()
    styles = {
        "Title": ParagraphStyle(
            "Title",
            parent=base["Title"],
            fontName="Helvetica-Bold",
            fontSize=26,
            leading=31,
            alignment=TA_CENTER,
            textColor=PRIMARY,
            spaceAfter=8,
        ),
        "Subtitle": ParagraphStyle(
            "Subtitle",
            parent=base["BodyText"],
            fontName="Helvetica",
            fontSize=11,
            leading=16,
            alignment=TA_CENTER,
            textColor=MUTED,
            spaceAfter=12,
        ),
        "SectionTitle": ParagraphStyle(
            "SectionTitle",
            parent=base["Heading1"],
            fontName="Helvetica-Bold",
            fontSize=16,
            leading=20,
            textColor=PRIMARY,
            borderPadding=(0, 0, 5, 0),
            borderColor=ACCENT,
            borderWidth=0,
            spaceBefore=4,
            spaceAfter=3,
        ),
        "SubsectionTitle": ParagraphStyle(
            "SubsectionTitle",
            parent=base["Heading2"],
            fontName="Helvetica-Bold",
            fontSize=11.5,
            leading=15,
            textColor=ACCENT,
            spaceBefore=6,
            spaceAfter=3,
        ),
        "Body": ParagraphStyle(
            "Body",
            parent=base["BodyText"],
            fontName="Helvetica",
            fontSize=9,
            leading=13,
            textColor=colors.HexColor("#222222"),
            spaceAfter=5,
        ),
        "SmallLabel": ParagraphStyle(
            "SmallLabel",
            parent=base["BodyText"],
            fontName="Helvetica-Bold",
            fontSize=8.5,
            leading=11,
            textColor=PRIMARY,
            spaceBefore=3,
            spaceAfter=2,
        ),
        "TableHeader": ParagraphStyle(
            "TableHeader",
            parent=base["BodyText"],
            fontName="Helvetica-Bold",
            fontSize=7.5,
            leading=10,
            textColor=colors.white,
        ),
        "TableCell": ParagraphStyle(
            "TableCell",
            parent=base["BodyText"],
            fontName="Helvetica",
            fontSize=7.5,
            leading=10,
            textColor=colors.HexColor("#222222"),
        ),
        "Note": ParagraphStyle(
            "Note",
            parent=base["BodyText"],
            fontName="Helvetica",
            fontSize=8.5,
            leading=12,
            textColor=colors.HexColor("#344054"),
            backColor=colors.HexColor("#F6FAFB"),
            borderColor=RULE,
            borderWidth=0.5,
            borderPadding=6,
            spaceBefore=4,
            spaceAfter=6,
        ),
        "Caption": ParagraphStyle(
            "Caption",
            parent=base["BodyText"],
            fontName="Helvetica-Oblique",
            fontSize=7.5,
            leading=10,
            textColor=MUTED,
            alignment=TA_CENTER,
            spaceBefore=3,
            spaceAfter=5,
        ),
    }

    story = []

    if LOGO.exists():
        story.append(Image(str(LOGO), width=26 * mm, height=26 * mm, kind="proportional"))
        story.append(Spacer(1, 6 * mm))

    story.extend(
        [
            Paragraph("Fleet Management System", styles["Title"]),
            Paragraph("Comprehensive User Manual", styles["Subtitle"]),
            Paragraph("Prepared for operational users, approvers, administrators, and reporting teams.", styles["Subtitle"]),
            Spacer(1, 8 * mm),
            workflow_table(
                [
                    ["Document", "Details"],
                    ["System", "Fleet Management System"],
                    ["Scope", "Vehicles, drivers, fuel, maintenance, compliance, logistics, reporting, settings, and administration"],
                    ["Version date", "July 13, 2026"],
                    ["Audience", "Fleet officers, drivers, maintenance teams, procurement, finance, approvers, auditors, and administrators"],
                ],
                [40 * mm, 118 * mm],
                styles,
            ),
            Spacer(1, 12 * mm),
            Paragraph(
                "This manual explains how to use the system day to day, how major workflows move through approval, and how administrators keep setup data accurate.",
                styles["Note"],
            ),
            PageBreak(),
        ]
    )

    story += section("1. Overview", styles)
    story.append(
        Paragraph(
            "The Fleet Management System manages the full operating cycle of an organization fleet: vehicle records, driver records, fuel usage, maintenance, workshops, tyres, parts, compliance documents, insurance, incidents, vehicle requests, trips, approvals, reports, and administration setup.",
            styles["Body"],
        )
    )
    story.append(
        Paragraph(
            "The application is permission based. Users only see the menu items and action buttons allowed for their role. If a page, button, or approval action is missing, an administrator should review the user's role and permissions.",
            styles["Body"],
        )
    )

    story += section("2. Getting Started", styles)
    story += subsection("Sign in", styles)
    story.append(numbered_items([
        "Open the system URL in a supported browser.",
        "Enter your username or email address and password.",
        "Select Login.",
        "If you forget your password, use Forgot Password and follow the reset link sent by email.",
    ], styles["Body"]))
    story += subsection("Main navigation", styles)
    story.append(
        workflow_table(
            [
                ["Area", "Purpose"],
                ["Dashboard", "Daily overview of fleet KPIs, alerts, recent activity, pending work, and operational exceptions."],
                ["Fleet", "Vehicles, drivers, driver off-duty periods, insurance, incidents, GPS tracking, and vehicle inspections."],
                ["Fuel", "Fuel vouchers and fuel cards."],
                ["Maintenance", "Maintenance jobs, service schedules, workshops, spare parts, and tyres."],
                ["Logistics", "Trips, vehicle requisitions, workflow approvals, expenses, and compliance renewals."],
                ["Intelligence", "AI insights, risk indicators, and recommendations where enabled."],
                ["Settings", "Company setup, users, permissions, reference data, alerts, and workflow templates."],
                ["Reports", "Operational reports, exports, audit logs, driver scorecards, and total cost views."],
                ["My Profile", "Personal profile details."],
                ["Logout", "Sign out of the application."],
            ],
            [36 * mm, 122 * mm],
            styles,
        )
    )

    story += section("3. Common Screen Controls", styles)
    story.append(bullet_items([
        "KPI cards show totals, alerts, and status summaries for the page.",
        "Search boxes filter lists by common fields such as vehicle, driver, workshop, plate number, or description.",
        "Status, stage, and date filters narrow records to the current work queue.",
        "Add, New, or Create buttons open a modal or form for a new record.",
        "Pencil icons edit records when the user has permission and the record is still editable.",
        "Eye icons open detail views or profiles.",
        "Trash icons remove records where deletion is permitted.",
        "Power icons activate or deactivate setup records.",
        "Export buttons download filtered records where export is available.",
    ], styles["Body"]))
    story.append(
        Paragraph(
            "Always save before closing a modal. For workflow decisions, enter clear comments when approving, rejecting, returning, cancelling, suspending, overriding policy, or requesting rework.",
            styles["Note"],
        )
    )

    story += section("4. Dashboard", styles)
    story.append(
        Paragraph(
            "Use the dashboard as the daily command center. It summarizes active fleet records, maintenance activity, compliance alerts, fuel activity, trip activity, recent actions, and exceptions that need attention.",
            styles["Body"],
        )
    )
    story += screenshot_block("01_dashboard.png", "Dashboard showing the fleet intelligence cockpit, KPI cards, activity timeline, and sidebar navigation.", styles)
    story.append(bullet_items([
        "Review overdue and expiring documents.",
        "Check pending approvals and delayed workflow stages.",
        "Monitor open maintenance jobs and vehicles in workshop.",
        "Look for unusual fuel usage, active trips, and operational exceptions.",
        "Use dashboard information to decide which module to open first.",
    ], styles["Body"]))

    story += section("5. Fleet Module", styles)
    story += screenshot_block("02_vehicles.png", "Vehicles register showing KPI cards, search, status filters, exports, and action buttons.", styles)
    story += screenshot_block("03_drivers.png", "Drivers register for managing driver records, search, and quick actions.", styles)
    story += screenshot_block("04_vehicle_inspection.png", "Vehicle Inspection page with filters, export controls, and the inspection table.", styles)
    modules = [
        (
            "Vehicles",
            "Use Fleet > Vehicles to maintain the central vehicle register.",
            [
                "Add vehicles with plate number, type, model, ownership, branch, department, mileage, and other required details.",
                "Edit vehicle information when ownership, assignment, mileage, or operating details change.",
                "Open a vehicle profile to review documents, insurance, maintenance, trips, usage, and costs.",
                "Use filters and search to locate vehicles by plate number, model, status, branch, or department.",
            ],
            "Keep vehicle type, model, owner, branch, and department setup records active and accurate so vehicle forms have correct dropdown values.",
        ),
        (
            "Drivers",
            "Use Fleet > Drivers to manage driver biodata, contact details, licenses, and operational records.",
            [
                "Create driver profiles with contact and employment details.",
                "Upload or update driver photos where enabled.",
                "Track license details, certifications, medical records, training, and violations.",
                "Open the driver profile for assignments, history, compliance checks, and performance context.",
            ],
            "Update driver records before assigning vehicles or approving trips so reporting and compliance checks remain reliable.",
        ),
        (
            "Driver Off-Duty",
            "Use Fleet > Driver Off-Duty to record dates or periods when a driver is unavailable.",
            [
                "Create off-duty entries for leave, suspension, sickness, training, or other unavailability.",
                "Review active and upcoming off-duty records before assigning trips.",
                "Update or close records when a driver returns to duty.",
            ],
            "Record off-duty periods early so vehicle assignment and trip planning do not rely on unavailable drivers.",
        ),
        (
            "Insurance",
            "Use Fleet > Insurance to record vehicle insurance policies and claims-related details.",
            [
                "Capture vehicle, insurer, policy number, coverage dates, premium, and status.",
                "Update policies before expiry.",
                "Record claim or payment follow-up details where available.",
                "Use reports to track expired, expiring, and active policies.",
            ],
            "Confirm that insurers are configured under Settings > Insurer Setup before entering policies.",
        ),
        (
            "Incidents",
            "Use Fleet > Incidents to log accidents, damage, traffic events, and other fleet incidents.",
            [
                "Capture vehicle, driver, date, location, severity, description, cost impact, and follow-up status.",
                "Attach or reference supporting evidence where the installation supports it.",
                "Review incidents when assessing driver risk or vehicle history.",
            ],
            "Enter incident details promptly and factually because they feed audit, insurance, cost, and driver scorecard views.",
        ),
        (
            "GPS Tracking",
            "Use Fleet > GPS Tracking to view or manage tracker-related vehicle information.",
            [
                "Review tracker-linked vehicle status.",
                "Check provider or integration information.",
                "Escalate missing tracker data to the administrator or integration owner.",
            ],
            "Configure providers and device settings under Settings > Tracker Integrations.",
        ),
        (
            "Vehicle Inspection",
            "Use Fleet > Vehicle Inspection to record inspection results and vehicle condition checks.",
            [
                "Create inspection entries for routine checks, handover checks, post-repair reviews, or compliance inspections.",
                "Record findings, condition notes, defects, and follow-up actions.",
                "Use inspection history when reviewing vehicle readiness.",
            ],
            "Use consistent inspection notes so maintenance teams can act on defects without needing clarification.",
        ),
    ]
    for item in modules:
        story.append(module_block(*item, styles))

    story += section("6. Fuel Module", styles)
    story += screenshot_block("05_fuel.png", "Fuel vouchers page for recording and reviewing fuel activity.", styles)
    story.append(module_block(
        "Fuel Vouchers",
        "Use Fuel > Fuel Vouchers to record and manage fuel requests, voucher usage, and vehicle fuel transactions.",
        [
            "Create a fuel entry for a vehicle or driver.",
            "Enter station, quantity, unit price, odometer, date, and supporting details.",
            "Submit or save the record according to the local process.",
            "Review approvals where required.",
            "Use fuel reports to monitor consumption, cost, and exceptions.",
        ],
        "Enter odometer values carefully. Incorrect readings distort consumption analysis and maintenance planning.",
        styles,
    ))
    story.append(module_block(
        "Fuel Cards",
        "Use Fuel > Fuel Cards to manage fuel cards assigned to vehicles, drivers, departments, or operational units.",
        [
            "Create fuel card records with card number, provider, assignment, status, and limits.",
            "Deactivate cards that are lost, expired, replaced, or no longer in use.",
            "Review card usage and exceptions where card integration is enabled.",
        ],
        "Deactivate unused cards immediately to reduce financial exposure.",
        styles,
    ))
    story.append(module_block(
        "Fuel Setup",
        "Use Settings > Fuel Setup to configure fuel-related reference data and rules used by the fuel module.",
        [
            "Maintain fuel types, pricing assumptions, stations, limits, and related setup records where configured.",
            "Review approval settings before changing operational fuel rules.",
        ],
        "Limit setup changes to authorized users because they affect transactions and reports.",
        styles,
    ))

    story += section("7. Maintenance Module", styles)
    story.append(
        Paragraph(
            "Use Maintenance > Maintenance to manage the complete lifecycle of vehicle repairs from complaint logging through final payment. The workflow uses stage-specific action buttons, RFQ controls, approval decisions, inspection steps, and audit timeline entries.",
            styles["Body"],
        )
    )
    story += screenshot_block("06_maintenance.png", "Maintenance command page showing job KPIs, workflow filters, export controls, and job actions.", styles)
    story.append(
        workflow_table(
            [
                ["Role", "Primary responsibilities"],
                ["Driver", "Log complaints."],
                ["Fleet Officer", "Log complaints and view jobs."],
                ["Fleet Manager", "Approve complaints and inspect work."],
                ["Maintenance Supervisor", "Review complaints, raise work orders, send job orders, and coordinate repairs."],
                ["Procurement Officer", "Invite RFQ vendors, capture quotes, and vet selected quotes."],
                ["Finance Manager", "Approve amounts, manage requisitions, and record payment outcomes."],
                ["HOD", "Approve amounts and apply policy overrides where permitted."],
                ["QC", "Inspect completed work."],
                ["Internal Auditor", "Validate internal control and close jobs."],
                ["Workshop or Vendor", "Carry out repairs and mark work done where permitted."],
                ["Admin", "Full access according to configured permissions."],
            ],
            [42 * mm, 116 * mm],
            styles,
        )
    )
    story += subsection("Maintenance workflow stages", styles)
    story.append(
        workflow_table(
            [
                ["Stage", "Main action", "Next result"],
                ["Complaint Logged", "Approve or reject complaint.", "Maintenance Review or Cancelled."],
                ["Maintenance Review", "Raise work order with line items and work order number.", "Work Order Raised."],
                ["Work Order Raised", "Send RFQ or send job order where permitted.", "RFQ Sent or Workshop In Progress."],
                ["RFQ Sent", "Invite vendors and capture quotes.", "Quote Submitted."],
                ["Quote Submitted", "Vet selected quote or approve final amount.", "Quote Vetted or Job Order Approved."],
                ["Quote Vetted", "Approve final amount.", "Job Order Approved."],
                ["Job Order Approved", "Send job order, suspend, or cancel.", "Workshop In Progress, Suspended, or Cancelled."],
                ["Workshop In Progress", "Mark work done when repairs are complete.", "Inspection."],
                ["Inspection", "Confirm work done or reject for rework.", "Internal Control or Workshop In Progress."],
                ["Internal Control", "Validate internal control.", "Closed."],
                ["Closed", "Raise payment requisition where required.", "Requisition Raised."],
                ["Requisition Raised", "Approve or reject requisition.", "Requisition Approved or Requisition Rejected."],
                ["Requisition Approved", "Make payment or record payment not made.", "Payment Made or Payment Not Made."],
                ["Requisition Rejected", "Send job order back for rework where needed.", "Workshop In Progress."],
                ["Payment Made", "Rate job order.", "Record remains Payment Made."],
                ["Suspended", "Resume or cancel job order.", "Workshop In Progress or Cancelled."],
            ],
            [34 * mm, 74 * mm, 50 * mm],
            styles,
        )
    )
    story += subsection("RFQ Manager", styles)
    story.append(bullet_items([
        "Open the RFQ Manager from the list-check icon on a maintenance job row.",
        "Invite workshop vendors from the vendor dropdown.",
        "Capture vendor quote documents, amounts, and line items.",
        "Compare quotes and select the final workshop.",
        "Use policy status panels to confirm whether minimum vendor and quote requirements are met.",
        "Use HOD Override only when policy allows and a clear reason is recorded.",
    ], styles["Body"]))
    story += subsection("Maintenance PDFs and timeline", styles)
    story.append(bullet_items([
        "Work Order PDF is available after a work order is raised.",
        "Job Order PDF is available after job order approval.",
        "The timeline shows stage changes, comments, amount changes, and the user who performed each action.",
        "Edit complaint details early; later workflow stages restrict editing to protect the quote and approval process.",
    ], styles["Body"]))
    story += subsection("Other maintenance areas", styles)
    story.append(bullet_items([
        "Service Schedules: create preventive maintenance intervals by date, mileage, or service plan.",
        "Workshop: manage workshop-facing job activity and assigned jobs.",
        "Parts: manage spare parts records, stock context, and usage.",
        "Tyres: manage tyre inventory, fitting, removal, retread, scrap, brand, and model history.",
    ], styles["Body"]))

    story += section("8. Logistics Module", styles)
    story += screenshot_block("07_vehicle_requisition.png", "Vehicle Requisition page for request tracking, workflow status, and assignment activity.", styles)
    story += screenshot_block("08_compliance.png", "Compliance renewal registry showing document KPIs, filters, and renewal history.", styles)
    story.append(module_block(
        "Trips",
        "Use Logistics > Trips to record journeys and vehicle usage.",
        [
            "Create trips with vehicle, driver, route, purpose, and start details.",
            "End the trip when completed.",
            "Enter final mileage and completion notes where required.",
            "Use trip records for utilization, driver, cost, and operational reporting.",
        ],
        "Close trips promptly so vehicles and drivers are available for accurate planning.",
        styles,
    ))
    story.append(module_block(
        "Vehicle Requisition",
        "Use Logistics > Vehicle Requisition to request vehicles for journeys, assignments, or operational movement.",
        [
            "Create a request with pickup, destination, purpose, dates, passenger count, priority, notes, and supporting document where needed.",
            "Save Draft while the request is incomplete or Submit when ready for approval.",
            "Approvers can approve, reject, return, or request correction based on workflow rules.",
            "After approval, an authorized user assigns a vehicle and optional driver.",
            "Use recommendations where available to compare suitable vehicles.",
        ],
        "Submit requests early and use clear journey details so approvers and assigners can act without delay.",
        styles,
    ))
    story.append(module_block(
        "Approvals",
        "Use Logistics > Approvals to act on workflow items awaiting your decision.",
        [
            "Open each item and review the details.",
            "Approve valid requests.",
            "Reject or return requests that need correction, adding a clear comment.",
            "Resubmit returned items after correction where your role permits it.",
        ],
        "Comments are part of the audit trail. Keep them professional, specific, and action oriented.",
        styles,
    ))
    story.append(module_block(
        "Expenses",
        "Use Logistics > Expenses to record operational expenses connected to vehicles, trips, drivers, or fleet activities.",
        [
            "Capture expense category, amount, date, vehicle, trip, driver, and description where applicable.",
            "Attach or reference evidence where supported.",
            "Review expense reports for reconciliation and cost control.",
        ],
        "Record expenses as soon as possible to keep cost reporting current.",
        styles,
    ))
    story.append(module_block(
        "Compliance",
        "Use Logistics > Compliance to track vehicle documents and renewals such as licenses, permits, roadworthiness, and regulatory obligations.",
        [
            "Create renewal records with vehicle, document type, issuing authority, issuing office, vendor, dates, and cost.",
            "Update records before expiry.",
            "Use compliance reports to find expired, expiring, and active records.",
            "Maintain setup values for authorities, offices, vendors, states, LGAs, branches, accounts, and owners.",
        ],
        "Do not wait until expiry day. Early renewal prevents operational disruption and enforcement risk.",
        styles,
    ))

    story += section("9. Intelligence", styles)
    story.append(
        Paragraph(
            "Use Intelligence > AI Insights to review system-generated recommendations, anomalies, and risk indicators. Available insights depend on the data captured in the installation.",
            styles["Body"],
        )
    )
    story.append(bullet_items([
        "Overdue maintenance or service risks.",
        "Abnormal fuel consumption.",
        "Underutilized vehicles.",
        "Driver incident or performance alerts.",
        "Route, assignment, or operational optimization opportunities.",
        "AI-assisted vehicle recommendations for approved requisitions where enabled.",
    ], styles["Body"]))

    story += section("10. Reports", styles)
    story += screenshot_block("09_reports.png", "Reports overview hub with operational, compliance, maintenance, audit, fuel, and TCO report shortcuts.", styles)
    story.append(
        workflow_table(
            [
                ["Report area", "Use"],
                ["Overview", "General report landing page and reporting shortcuts."],
                ["Compliance Reports", "Document status, expiry, renewal, and compliance views."],
                ["Vehicle Reports", "Fleet register and vehicle-related operational views."],
                ["Driver Reports", "Driver records, compliance, and driver-related views."],
                ["Workshop Reports", "Workshop and repair activity."],
                ["Maintenance Reports", "Maintenance jobs and workflow status."],
                ["Fuel Request Report", "Fuel request and voucher reporting."],
                ["TCO Report", "Total cost of ownership by vehicle."],
                ["Data Import/Export", "Bulk data movement, imports, and exports."],
                ["Audit Logs", "Immutable activity history and verification tools."],
                ["Driver Scorecard", "Driver performance and risk scoring."],
            ],
            [45 * mm, 113 * mm],
            styles,
        )
    )
    story.append(
        Paragraph(
            "Use filters before exporting so downloaded reports contain the exact period, status, category, branch, vehicle, or driver needed.",
            styles["Note"],
        )
    )

    story += section("11. Administration and Setup", styles)
    story.append(
        Paragraph(
            "Administration pages are normally restricted to administrators, module owners, or managers. Setup data feeds dropdowns, validation rules, routing, reports, generated documents, and workflow controls.",
            styles["Body"],
        )
    )
    story += screenshot_block("10_settings.png", "Settings overview showing setup areas for compliance, fuel, users, permissions, reports, and alerts.", styles)
    story.append(
        workflow_table(
            [
                ["Setup area", "Examples"],
                ["Company and users", "Company Setup, Users, Permissions, My Profile."],
                ["Geography", "States, LGAs, Regions, Cities, Locations."],
                ["Organization", "Branches, Departments, Projects, Contract Types, Accounts, Owners."],
                ["Fleet setup", "Vehicle Types, Vehicle Models, Insurer Setup, Tracker Integrations."],
                ["Compliance setup", "Compliance Setup, Issuing Authorities, Issuing Offices, Compliance Vendors."],
                ["Maintenance setup", "Supplier Setup, Part Catalog Setup, Bin Location Setup, Tyre Brand Setup, Tyre Model Setup."],
                ["Fuel setup", "Fuel Setup and related fuel rules."],
                ["Workflow and alerts", "Workflow Templates and Alert Delivery."],
            ],
            [44 * mm, 114 * mm],
            styles,
        )
    )
    story += subsection("Users and permissions", styles)
    story.append(bullet_items([
        "Create users with accurate names, contact details, and role assignments.",
        "Activate or deactivate accounts as staff responsibilities change.",
        "Review permissions when users cannot see menu items, buttons, pages, or approval actions.",
        "Change permissions carefully because they affect operational controls and audit accountability.",
    ], styles["Body"]))
    story += subsection("Alert delivery", styles)
    story.append(
        Paragraph(
            "Use Settings > Alert Delivery to review alert delivery activity and provider responses. Email delivery depends on the configured SMTP or mail settings. If alerts are not delivered, an administrator should verify mail configuration and test delivery.",
            styles["Body"],
        )
    )
    story += subsection("Workflow templates", styles)
    story.append(
        Paragraph(
            "Use Settings > Workflow Templates to configure reusable approval workflows. Only authorized users should modify templates because they control approval routing, responsibilities, and process behavior.",
            styles["Body"],
        )
    )

    story += section("12. Data Import and Export", styles)
    story.append(bullet_items([
        "Use Reports > Data Import/Export for bulk data movement.",
        "Download or prepare the correct template before importing.",
        "Keep column headers unchanged.",
        "Validate dates, numbers, vehicle plates, driver identifiers, and lookup values before upload.",
        "Import a small sample first when working with a new file format.",
        "Review result messages and correct failed rows before retrying.",
        "Use exports for offline analysis, reconciliation, audit support, and management reporting.",
    ], styles["Body"]))

    story += section("13. Audit and Accountability", styles)
    story.append(
        Paragraph(
            "The system records important actions in audit logs, including user actions, workflow transitions, comments, selected data changes, approval decisions, and overrides.",
            styles["Body"],
        )
    )
    story.append(bullet_items([
        "Use your own login only.",
        "Do not share passwords.",
        "Add clear comments for approvals, rejections, returns, suspensions, cancellations, overrides, and payment exceptions.",
        "Review audit logs when investigating disputes, missing actions, process delays, or compliance exceptions.",
        "Use exports only for authorized business purposes.",
    ], styles["Body"]))

    story += section("14. Troubleshooting", styles)
    story.append(
        workflow_table(
            [
                ["Issue", "What to check"],
                ["I cannot see a menu item.", "Your role may not have the required permission. Ask an administrator to check Settings > Users and Settings > Permissions."],
                ["A Save button fails or shows Unauthorized.", "You may have view access but not create, edit, approve, or delete access."],
                ["A dropdown is empty.", "The related setup table may not have active records. Check setup pages such as vehicle types, departments, suppliers, insurers, or issuing authorities."],
                ["I cannot submit or approve a workflow.", "Confirm required fields, comments, line items, final workshop, approved amounts, or override reasons are complete."],
                ["Email alerts are not delivered.", "Ask an administrator to verify SMTP settings, mail credentials, and the mail test script."],
                ["A report does not show expected records.", "Clear filters, check date range and status, confirm the record exists, and verify your role has access."],
                ["A maintenance action is disabled.", "Check the current workflow stage and whether prerequisite RFQ, quote, amount, or workshop data has been entered."],
            ],
            [48 * mm, 110 * mm],
            styles,
        )
    )

    story += section("15. Recommended Daily Routine", styles)
    story.append(numbered_items([
        "Review Dashboard alerts and pending work.",
        "Open Approvals and act on items awaiting your decision.",
        "Review expiring documents in Compliance or Compliance Reports.",
        "Check active maintenance jobs and delayed workflow stages.",
        "Monitor fuel usage, exceptions, and pending fuel activity.",
        "Update trips, requisitions, incidents, expenses, and inspections before end of day.",
        "Export or review reports needed for management follow-up.",
        "Log out when finished, especially on shared devices.",
    ], styles["Body"]))

    doc.build(story, onFirstPage=add_page_number, onLaterPages=add_page_number)


if __name__ == "__main__":
    build_pdf()
    print(OUTPUT_PDF)
