"""
setup_flow_templates.py — Create doctypes for the Flow Editor (project/service
orchestration engine).

Three doctypes:
  - Flow Template     : editable template library (admins manage in SettingsPage)
  - Flow Run          : per-execution state attached to a context doc
  - Flow Step Pending : scheduled steps waiting for a time/condition trigger

Run inside the bench container:
  docker compose exec backend bench --site <site> execute setup_flow_templates.create_all

Or via docker exec python path (avoids IPython cell-split gotcha):
  docker exec -u frappe erpnext-backend-1 bash -c \\
    'cd /home/frappe/frappe-bench/sites && \\
     /home/frappe/frappe-bench/env/bin/python -c \\
     "import frappe; frappe.init(site=\\"erp.gigafibre.ca\\"); frappe.connect(); \\
      from setup_flow_templates import create_all; create_all()"'
"""

import frappe


def create_all():
    _create_flow_template()
    _create_flow_run()
    _create_flow_step_pending()
    frappe.db.commit()
    print("[OK] Flow Editor doctypes created.")


# -----------------------------------------------------------------------------
# Flow Template — editable template library
# -----------------------------------------------------------------------------

def _create_flow_template():
    if frappe.db.exists("DocType", "Flow Template"):
        print("  Flow Template already exists — skipping.")
        return

    doc = frappe.get_doc({
        "doctype": "DocType",
        "name": "Flow Template",
        "module": "Dispatch",
        "custom": 1,
        "autoname": "FT-.#####",
        "track_changes": 1,
        "fields": [
            # -- Identification ---------------------------------------------
            {"fieldname": "template_name", "fieldtype": "Data", "label": "Nom du template",
             "reqd": 1, "in_list_view": 1, "unique": 1,
             "description": "Nom court et descriptif (ex: Installation fibre résidentielle)"},
            {"fieldname": "category", "fieldtype": "Select", "label": "Catégorie",
             "options": "Internet\nTéléphonie\nTélévision\nDéménagement\nRéparation\nOnboarding\nRenouvellement\nChurn\nDépannage\nCustom",
             "default": "Custom", "in_list_view": 1, "reqd": 1},
            {"fieldname": "applies_to", "fieldtype": "Select", "label": "S'applique à",
             "options": "Quotation\nService Contract\nIssue\nCustomer\nSubscription",
             "default": "Service Contract", "in_list_view": 1, "reqd": 1,
             "description": "Type de document qui déclenche le flow"},
            {"fieldname": "col_id1", "fieldtype": "Column Break"},
            {"fieldname": "icon", "fieldtype": "Data", "label": "Icône (Material)",
             "default": "account_tree",
             "description": "Nom d'icône Quasar/Material (ex: cable, phone_in_talk)"},
            {"fieldname": "is_active", "fieldtype": "Check", "label": "Actif",
             "default": "1", "in_list_view": 1},
            {"fieldname": "is_system", "fieldtype": "Check", "label": "Template système",
             "default": "0", "read_only": 1,
             "description": "Templates seedés — ne pas supprimer"},
            {"fieldname": "version", "fieldtype": "Int", "label": "Version",
             "default": "1", "read_only": 1,
             "description": "Incrémenté à chaque sauvegarde"},

            # -- Description ------------------------------------------------
            {"fieldname": "sec_desc", "fieldtype": "Section Break", "label": "Description"},
            {"fieldname": "description", "fieldtype": "Small Text", "label": "Description",
             "description": "Phrase courte expliquant ce que fait le flow"},

            # -- Déclencheur (trigger) --------------------------------------
            {"fieldname": "sec_trigger", "fieldtype": "Section Break",
             "label": "Déclencheur automatique",
             "description": "Quand ce flow doit-il se déclencher automatiquement?"},
            {"fieldname": "trigger_event", "fieldtype": "Select", "label": "Évènement",
             "options": "\nmanual\non_quotation_created\non_quotation_accepted\non_contract_signed\non_payment_received\non_subscription_active\non_issue_opened\non_customer_created\non_dispatch_completed",
             "default": "manual",
             "description": "manual = démarré à la main depuis ProjectWizard ou un bouton"},
            {"fieldname": "col_trigger", "fieldtype": "Column Break"},
            {"fieldname": "trigger_condition", "fieldtype": "Small Text",
             "label": "Condition (expression)",
             "description": "Expression JS/Python (ex: contract.contract_type == 'Résidentiel'). Vide = toujours."},

            # -- Définition du flow (JSON) ---------------------------------
            {"fieldname": "sec_def", "fieldtype": "Section Break", "label": "Définition du flow"},
            {"fieldname": "flow_definition", "fieldtype": "Long Text",
             "label": "Flow definition (JSON)", "reqd": 1,
             "description": "Arbre complet des étapes. Éditer via SettingsPage > Flows."},
            {"fieldname": "step_count", "fieldtype": "Int", "label": "Nombre d'étapes",
             "read_only": 1, "in_list_view": 1,
             "description": "Calculé à la sauvegarde"},

            # -- Métadonnées ------------------------------------------------
            {"fieldname": "sec_meta", "fieldtype": "Section Break",
             "label": "Métadonnées", "collapsible": 1},
            {"fieldname": "tags", "fieldtype": "Data", "label": "Tags (CSV)",
             "description": "Étiquettes libres (ex: résidentiel,fibre,nouveau-client)"},
            {"fieldname": "notes", "fieldtype": "Small Text", "label": "Notes internes"},
        ],
        "permissions": [
            {"role": "System Manager", "read": 1, "write": 1, "create": 1, "delete": 1},
            {"role": "Dispatch User", "read": 1, "write": 1, "create": 1},
            {"role": "Sales User", "read": 1},
        ],
    })
    doc.insert(ignore_permissions=True)
    print("  [+] Flow Template doctype created.")


# -----------------------------------------------------------------------------
# Flow Run — one execution instance per context doc
# -----------------------------------------------------------------------------

def _create_flow_run():
    if frappe.db.exists("DocType", "Flow Run"):
        print("  Flow Run already exists — skipping.")
        return

    doc = frappe.get_doc({
        "doctype": "DocType",
        "name": "Flow Run",
        "module": "Dispatch",
        "custom": 1,
        "autoname": "FR-.######",
        "track_changes": 1,
        "fields": [
            # -- Identification ---------------------------------------------
            {"fieldname": "flow_template", "fieldtype": "Link", "label": "Flow Template",
             "options": "Flow Template", "reqd": 1, "in_list_view": 1},
            {"fieldname": "template_version", "fieldtype": "Int",
             "label": "Version du template au démarrage", "read_only": 1,
             "description": "Figée au démarrage — une modif ultérieure du template n'affecte pas ce run"},
            {"fieldname": "col_run1", "fieldtype": "Column Break"},
            {"fieldname": "status", "fieldtype": "Select", "label": "Statut",
             "options": "pending\nrunning\nwaiting\ncompleted\nfailed\ncancelled",
             "default": "pending", "reqd": 1, "in_list_view": 1},
            {"fieldname": "trigger_event", "fieldtype": "Data", "label": "Déclencheur",
             "description": "Évènement qui a démarré ce run"},

            # -- Contexte (doc qui a déclenché) ----------------------------
            {"fieldname": "sec_ctx", "fieldtype": "Section Break", "label": "Contexte"},
            {"fieldname": "context_doctype", "fieldtype": "Link",
             "label": "DocType de contexte", "options": "DocType",
             "in_list_view": 1},
            {"fieldname": "context_docname", "fieldtype": "Dynamic Link",
             "label": "Document", "options": "context_doctype", "in_list_view": 1},
            {"fieldname": "col_ctx", "fieldtype": "Column Break"},
            {"fieldname": "customer", "fieldtype": "Link", "label": "Client",
             "options": "Customer", "in_list_view": 1},
            {"fieldname": "variables", "fieldtype": "Long Text",
             "label": "Variables (JSON)",
             "description": "Variables accumulées pendant l'exécution (pour les conditions/templates)"},

            # -- État d'exécution ------------------------------------------
            {"fieldname": "sec_state", "fieldtype": "Section Break", "label": "Exécution"},
            {"fieldname": "step_state", "fieldtype": "Long Text",
             "label": "État des étapes (JSON)",
             "description": "{stepId: {status, started_at, completed_at, result, error}}"},
            {"fieldname": "current_step_ids", "fieldtype": "Small Text",
             "label": "Étapes en cours (CSV)",
             "description": "IDs des étapes actuellement running/waiting"},
            {"fieldname": "col_state", "fieldtype": "Column Break"},
            {"fieldname": "started_at", "fieldtype": "Datetime",
             "label": "Démarré le", "read_only": 1},
            {"fieldname": "completed_at", "fieldtype": "Datetime",
             "label": "Terminé le", "read_only": 1},
            {"fieldname": "last_error", "fieldtype": "Small Text",
             "label": "Dernière erreur", "read_only": 1},
        ],
        "permissions": [
            {"role": "System Manager", "read": 1, "write": 1, "create": 1, "delete": 1},
            {"role": "Dispatch User", "read": 1, "write": 1},
        ],
    })
    doc.insert(ignore_permissions=True)
    print("  [+] Flow Run doctype created.")


# -----------------------------------------------------------------------------
# Flow Step Pending — scheduled/waiting steps picked up by cron
# -----------------------------------------------------------------------------

def _create_flow_step_pending():
    if frappe.db.exists("DocType", "Flow Step Pending"):
        print("  Flow Step Pending already exists — skipping.")
        return

    doc = frappe.get_doc({
        "doctype": "DocType",
        "name": "Flow Step Pending",
        "module": "Dispatch",
        "custom": 1,
        "autoname": "FSP-.######",
        "track_changes": 1,
        "fields": [
            {"fieldname": "flow_run", "fieldtype": "Link", "label": "Flow Run",
             "options": "Flow Run", "reqd": 1, "in_list_view": 1},
            {"fieldname": "step_id", "fieldtype": "Data", "label": "Step ID",
             "reqd": 1, "in_list_view": 1,
             "description": "ID de l'étape dans le flow_definition du template"},
            {"fieldname": "col_sp1", "fieldtype": "Column Break"},
            {"fieldname": "status", "fieldtype": "Select", "label": "Statut",
             "options": "waiting\nexecuting\ndone\nfailed\ncancelled",
             "default": "waiting", "reqd": 1, "in_list_view": 1},
            {"fieldname": "trigger_at", "fieldtype": "Datetime",
             "label": "Déclencher à", "reqd": 1, "in_list_view": 1,
             "description": "Le scheduler exécute l'étape quand NOW() >= trigger_at"},

            {"fieldname": "sec_ctx", "fieldtype": "Section Break", "label": "Contexte"},
            {"fieldname": "context_snapshot", "fieldtype": "Long Text",
             "label": "Snapshot contexte (JSON)",
             "description": "Variables du flow_run figées au moment où l'étape a été mise en attente"},

            {"fieldname": "sec_exec", "fieldtype": "Section Break", "label": "Exécution"},
            {"fieldname": "executed_at", "fieldtype": "Datetime",
             "label": "Exécuté le", "read_only": 1},
            {"fieldname": "last_error", "fieldtype": "Small Text",
             "label": "Erreur", "read_only": 1},
            {"fieldname": "retry_count", "fieldtype": "Int",
             "label": "Nb tentatives", "default": "0", "read_only": 1},
        ],
        "permissions": [
            {"role": "System Manager", "read": 1, "write": 1, "create": 1, "delete": 1},
            {"role": "Dispatch User", "read": 1, "write": 1},
        ],
    })
    doc.insert(ignore_permissions=True)
    print("  [+] Flow Step Pending doctype created.")
