#!/usr/bin/env python3
"""
Migration script: Convert legacy is_good field to type field across all data.

Steps:
1. tasks.json: is_good=True → type='chore', is_good=False → type='penalty'. Remove is_good field.
2. pending_rewards.json → pending_confirmations.json: Convert PendingReward records to
   PendingConfirmation format with entity_type='reward'.
3. tracking_events.json: Update entity_type='task' → 'chore' or 'penalty' based on the
   referenced task's old is_good value.
4. child_overrides.json: Update entity_type='task' → 'chore' or 'penalty' based on the
   referenced task's old is_good value.

Usage:
    cd backend
    python -m scripts.migrate_tasks_to_types [--dry-run]
"""

import json
import os
import sys
import shutil
from datetime import datetime

DRY_RUN = '--dry-run' in sys.argv

DATA_DIR = os.path.join(os.path.dirname(__file__), '..', 'data', 'db')


def load_json(filename: str) -> dict:
    path = os.path.join(DATA_DIR, filename)
    if not os.path.exists(path):
        return {"_default": {}}
    with open(path, 'r', encoding='utf-8') as f:
        return json.load(f)


def save_json(filename: str, data: dict) -> None:
    path = os.path.join(DATA_DIR, filename)
    if DRY_RUN:
        print(f"  [DRY RUN] Would write {path}")
        return
    # Backup original
    backup_path = path + f'.bak.{datetime.now().strftime("%Y%m%d_%H%M%S")}'
    if os.path.exists(path):
        shutil.copy2(path, backup_path)
        print(f"  Backed up {path} → {backup_path}")
    with open(path, 'w', encoding='utf-8') as f:
        json.dump(data, f, indent=2, ensure_ascii=False)
    print(f"  Wrote {path}")


def migrate_tasks() -> dict[str, str]:
    """Migrate tasks.json: is_good → type. Returns task_id → type mapping."""
    print("\n=== Step 1: Migrate tasks.json ===")
    data = load_json('tasks.json')
    task_type_map: dict[str, str] = {}
    migrated = 0
    already_done = 0

    for key, record in data.get("_default", {}).items():
        if 'type' in record and 'is_good' not in record:
            # Already migrated
            task_type_map[key] = record['type']
            already_done += 1
            continue

        if 'is_good' in record:
            is_good = record.pop('is_good')
            record['type'] = 'chore' if is_good else 'penalty'
            task_type_map[key] = record['type']
            migrated += 1
        elif 'type' in record:
            # Has both type and is_good — just remove is_good
            task_type_map[key] = record['type']
            already_done += 1
        else:
            # No is_good and no type — default to chore
            record['type'] = 'chore'
            task_type_map[key] = 'chore'
            migrated += 1

    print(f"  Migrated: {migrated}, Already done: {already_done}")
    if migrated > 0:
        save_json('tasks.json', data)
    else:
        print("  No changes needed.")
    return task_type_map


def migrate_pending_rewards() -> None:
    """Convert pending_rewards.json → pending_confirmations.json."""
    print("\n=== Step 2: Migrate pending_rewards.json → pending_confirmations.json ===")
    pr_data = load_json('pending_rewards.json')
    pc_path = os.path.join(DATA_DIR, 'pending_confirmations.json')

    if not os.path.exists(os.path.join(DATA_DIR, 'pending_rewards.json')):
        print("  pending_rewards.json not found — skipping.")
        return

    records = pr_data.get("_default", {})
    if not records:
        print("  No pending reward records to migrate.")
        return

    # Load existing pending_confirmations if it exists
    pc_data = load_json('pending_confirmations.json')
    pc_records = pc_data.get("_default", {})

    # Find the next key
    next_key = max((int(k) for k in pc_records), default=0) + 1

    migrated = 0
    for key, record in records.items():
        # Convert PendingReward → PendingConfirmation
        new_record = {
            'child_id': record.get('child_id', ''),
            'entity_id': record.get('reward_id', ''),
            'entity_type': 'reward',
            'user_id': record.get('user_id', ''),
            'status': record.get('status', 'pending'),
            'approved_at': None,
            'created_at': record.get('created_at', 0),
            'updated_at': record.get('updated_at', 0),
        }
        pc_records[str(next_key)] = new_record
        next_key += 1
        migrated += 1

    print(f"  Migrated {migrated} pending reward records to pending_confirmations.")
    pc_data["_default"] = pc_records
    save_json('pending_confirmations.json', pc_data)


def migrate_tracking_events(task_type_map: dict[str, str]) -> None:
    """Update entity_type='task' → 'chore'/'penalty' in tracking_events.json."""
    print("\n=== Step 3: Migrate tracking_events.json ===")
    data = load_json('tracking_events.json')
    records = data.get("_default", {})
    migrated = 0

    for key, record in records.items():
        if record.get('entity_type') == 'task':
            entity_id = record.get('entity_id', '')
            # Look up the task's type
            new_type = task_type_map.get(entity_id, 'chore')  # default to chore
            record['entity_type'] = new_type
            migrated += 1

    print(f"  Migrated {migrated} tracking event records.")
    if migrated > 0:
        save_json('tracking_events.json', data)
    else:
        print("  No changes needed.")


def migrate_child_overrides(task_type_map: dict[str, str]) -> None:
    """Update entity_type='task' → 'chore'/'penalty' in child_overrides.json."""
    print("\n=== Step 4: Migrate child_overrides.json ===")
    data = load_json('child_overrides.json')
    records = data.get("_default", {})
    migrated = 0

    for key, record in records.items():
        if record.get('entity_type') == 'task':
            entity_id = record.get('entity_id', '')
            new_type = task_type_map.get(entity_id, 'chore')  # default to chore
            record['entity_type'] = new_type
            migrated += 1

    print(f"  Migrated {migrated} child override records.")
    if migrated > 0:
        save_json('child_overrides.json', data)
    else:
        print("  No changes needed.")


def main() -> None:
    print("=" * 60)
    print("Task Type Migration Script")
    if DRY_RUN:
        print("*** DRY RUN MODE — no files will be modified ***")
    print("=" * 60)

    task_type_map = migrate_tasks()
    migrate_pending_rewards()
    migrate_tracking_events(task_type_map)
    migrate_child_overrides(task_type_map)

    print("\n" + "=" * 60)
    print("Migration complete!" + (" (DRY RUN)" if DRY_RUN else ""))
    print("=" * 60)


if __name__ == '__main__':
    main()
