#!/usr/bin/env python3
"""Disable pending automatic CONFIRM_DELIVERY tasks.

Dry-run is the default. With ``--apply`` the script marks pending automatic
CONFIRM_DELIVERY tasks as ignored. Manual delivery checks created explicitly by
an operator are preserved. No customer communication is sent.
"""
from __future__ import annotations

import argparse
from pathlib import Path
import sys

PROJECT_ROOT = Path(__file__).resolve().parents[1]
if str(PROJECT_ROOT) not in sys.path:
    sys.path.insert(0, str(PROJECT_ROOT))

from sqlalchemy import text


AUTOMATIC_FILTER = """
    t.status = 'pending'
    AND t.action_code = 'CONFIRM_DELIVERY'
    AND t.source_system = 'clientflow_followup'
    AND COALESCE(t.metadata->>'follow_up_reason', '') <> 'MANUAL_DELIVERY_CHECK'
    AND COALESCE(t.metadata->>'follow_up_purpose', '') <> 'manual_delivery_check'
    AND COALESCE(t.metadata->>'created_by', '') NOT IN ('operator', 'operator_ui')
"""


def main() -> int:
    parser = argparse.ArgumentParser()
    parser.add_argument("--apply", action="store_true", help="Ignore automatic tasks. Default is dry-run.")
    args = parser.parse_args()

    from app.db import engine

    with engine.begin() as conn:
        rows = conn.execute(text(f"""
            SELECT
                t.id::text AS task_id,
                o.id::text AS opportunity_id,
                o.customer_name,
                o.stage,
                COALESCE(o.value_amount, 0) AS value_amount,
                COALESCE(t.metadata->>'created_by', '') AS created_by
            FROM tasks t
            JOIN opportunities o ON o.id = t.opportunity_id
            WHERE {AUTOMATIC_FILTER}
            ORDER BY COALESCE(o.value_amount, 0) DESC, o.customer_name
        """)).mappings().all()

        print(f"Pending automatic CONFIRM_DELIVERY tasks: {len(rows)}")
        for row in rows:
            print(
                f"{row['stage']:18} | {float(row['value_amount'] or 0):9.2f} | "
                f"{row['customer_name']} | {row['created_by'] or 'unknown'}"
            )

        if not args.apply or not rows:
            if not args.apply:
                print("Dry-run only. Use --apply after reviewing the tasks.")
            return 0

        # SQL source marker for regression tests; f-strings below escape braces:
        # metadata = COALESCE(t.metadata, '{}'::jsonb)
        result = conn.execute(text(f"""
            WITH closed AS (
                UPDATE tasks t
                SET status = 'ignored',
                    done_at = COALESCE(t.done_at, now()),
                    done_by = 'migration_v4928_1_5_127',
                    updated_at = now(),
                    metadata = COALESCE(t.metadata, '{{}}'::jsonb) || jsonb_build_object(
                        'automatic_confirm_delivery_disabled', TRUE,
                        'automatic_confirm_delivery_disabled_at', now()::text,
                        'automatic_confirm_delivery_disabled_by', 'migration_v4928_1_5_127'
                    )
                FROM opportunities o
                WHERE o.id = t.opportunity_id
                  AND {AUTOMATIC_FILTER}
                RETURNING t.opportunity_id
            ), affected AS (
                SELECT DISTINCT opportunity_id FROM closed
            ), reset AS (
                UPDATE opportunities o
                SET lifecycle_state = CASE
                        WHEN o.lifecycle_state = 'awaiting_customer'
                         AND NOT EXISTS (
                            SELECT 1 FROM tasks p
                            WHERE p.opportunity_id = o.id
                              AND p.status = 'pending'
                              AND COALESCE(p.action_required, TRUE) = TRUE
                              AND NOT (
                                  p.action_code = 'CONFIRM_DELIVERY'
                                  AND p.source_system = 'clientflow_followup'
                                  AND COALESCE(p.metadata->>'follow_up_reason', '') <> 'MANUAL_DELIVERY_CHECK'
                                  AND COALESCE(p.metadata->>'follow_up_purpose', '') <> 'manual_delivery_check'
                                  AND COALESCE(p.metadata->>'created_by', '') NOT IN ('operator', 'operator_ui')
                              )
                         )
                        THEN 'active'
                        ELSE o.lifecycle_state
                    END,
                    next_follow_up_at = CASE
                        WHEN NOT EXISTS (
                            SELECT 1 FROM tasks p
                            WHERE p.opportunity_id = o.id
                              AND p.status = 'pending'
                              AND COALESCE(p.action_required, TRUE) = TRUE
                              AND NOT (
                                  p.action_code = 'CONFIRM_DELIVERY'
                                  AND p.source_system = 'clientflow_followup'
                                  AND COALESCE(p.metadata->>'follow_up_reason', '') <> 'MANUAL_DELIVERY_CHECK'
                                  AND COALESCE(p.metadata->>'follow_up_purpose', '') <> 'manual_delivery_check'
                                  AND COALESCE(p.metadata->>'created_by', '') NOT IN ('operator', 'operator_ui')
                              )
                        )
                        THEN NULL
                        ELSE o.next_follow_up_at
                    END,
                    updated_at = now(),
                    metadata = COALESCE(o.metadata, '{{}}'::jsonb) || jsonb_build_object(
                        'automatic_confirm_delivery_disabled', TRUE,
                        'automatic_confirm_delivery_disabled_at', now()::text
                    )
                WHERE o.id IN (SELECT opportunity_id FROM affected)
                RETURNING o.id
            )
            SELECT
                (SELECT COUNT(*) FROM closed)::int AS tasks_closed,
                (SELECT COUNT(*) FROM reset)::int AS opportunities_reviewed
        """)).mappings().one()

    print(f"Tasks ignored: {result['tasks_closed']}")
    print(f"Opportunities reviewed: {result['opportunities_reviewed']}")
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
