#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Demo Pool to Loaner Products Migration Script

Reads all records from the Studio-created x_demo_pool_tracking table
and creates proper product.template records with x_fc_can_be_loaned=True,
plus stock.lot serial numbers where applicable.

Run via Odoo shell:
    docker exec -i odoo-mobility-app odoo shell -d mobility < import_demo_pool.py

Or from the host with the script mounted:
    docker exec -i odoo-mobility-app odoo shell -d mobility \
        < /mnt/extra-addons/fusion_claims/scripts/import_demo_pool.py

Copyright 2024-2026 Nexa Systems Inc.
License OPL-1 (Odoo Proprietary License v1.0)
"""

import json
import logging

_logger = logging.getLogger(__name__)

EQUIPMENT_TYPE_MAP = {
    'Type 1 Walker': 'type_1_walker',
    'Type 2 MW': 'type_2_mw',
    'Type 2 PW': 'type_2_pw',
    'Type 2 Walker': 'type_2_walker',
    'Type 3 MW': 'type_3_mw',
    'Type 3 PW': 'type_3_pw',
    'Type 3 Walker': 'type_3_walker',
    'Type 4 MW': 'type_4_mw',
    'Type 5 MW': 'type_5_mw',
    'Ceiling Lift': 'ceiling_lift',
    'Mobility Scooter': 'mobility_scooter',
    'Patient Lift': 'patient_lift',
    'Transport Wheelchair': 'transport_wheelchair',
    'Wheelchair': 'standard_wheelchair',
    'Standard Wheelchair': 'standard_wheelchair',
    'Power Wheelchair': 'power_wheelchair',
    'Cushion': 'cushion',
    'Backrest': 'backrest',
    'Stairlift': 'stairlift',
    'Others': 'others',
}

WHEELCHAIR_CATEGORY_MAP = {
    'Type 1': 'type_1',
    'Type 2': 'type_2',
    'Type 3': 'type_3',
    'Type 4': 'type_4',
    'Type 5': 'type_5',
}

LOCATION_MAP = {
    'Warehouse': 'warehouse',
    'Westin Brampton': 'westin_brampton',
    'Mobility Etobicoke': 'mobility_etobicoke',
    'Scarborough Storage': 'scarborough_storage',
    'Client/Loaned': 'client_loaned',
    'Rented Out': 'rented_out',
}

LISTING_TYPE_MAP = {
    'Owned': 'owned',
    'Borrowed': 'borrowed',
}

SKIP_SERIALS = {'na', 'n/a', 'update', 'updated', ''}


def extract_name(json_val):
    """Extract English name from Odoo JSONB field."""
    if not json_val:
        return ''
    if isinstance(json_val, dict):
        return json_val.get('en_US', '') or ''
    if isinstance(json_val, str):
        try:
            parsed = json.loads(json_val)
            if isinstance(parsed, dict):
                return parsed.get('en_US', '') or ''
        except (json.JSONDecodeError, TypeError):
            return json_val
    return str(json_val)


def get_category_id(env, equipment_type_key):
    """Map equipment type to an appropriate product category."""
    loaner_cat = env.ref('fusion_claims.product_category_loaner', raise_if_not_found=False)
    wheelchair_cat = env.ref('fusion_claims.product_category_loaner_wheelchair', raise_if_not_found=False)
    powerchair_cat = env.ref('fusion_claims.product_category_loaner_powerchair', raise_if_not_found=False)
    rollator_cat = env.ref('fusion_claims.product_category_loaner_rollator', raise_if_not_found=False)

    if not loaner_cat:
        return env['product.category'].search([], limit=1).id

    wheelchair_types = {
        'type_2_mw', 'type_3_mw', 'type_4_mw', 'type_5_mw',
        'type_2_walker', 'type_3_walker', 'type_1_walker',
        'standard_wheelchair', 'transport_wheelchair',
    }
    powerchair_types = {'type_2_pw', 'type_3_pw', 'power_wheelchair'}
    rollator_types = set()

    if equipment_type_key in powerchair_types and powerchair_cat:
        return powerchair_cat.id
    if equipment_type_key in wheelchair_types and wheelchair_cat:
        return wheelchair_cat.id
    if equipment_type_key in rollator_types and rollator_cat:
        return rollator_cat.id
    return loaner_cat.id


def fetch_accessories(cr, demo_pool_id):
    """Fetch accessory lines from x_demo_pool_tracking_line_b4ec9."""
    cr.execute("""
        SELECT x_name FROM x_demo_pool_tracking_line_b4ec9
        WHERE x_demo_pool_tracking_id = %s
        ORDER BY x_studio_sequence, id
    """, (demo_pool_id,))
    rows = cr.fetchall()
    accessories = []
    for row in rows:
        name = extract_name(row[0])
        if name:
            accessories.append(name)
    return accessories


def run_import(env):
    cr = env.cr
    ProductTemplate = env['product.template']
    StockLot = env['stock.lot']

    company = env.company

    cr.execute("""
        SELECT
            id, x_name, x_studio_equipment_type, x_studio_wheelchair_categorytype,
            x_studio_serial_number, x_studio_seat_width, x_studio_seat_depth,
            x_studio_seat_height, x_studio_where_is_it_located, x_studio_listing_type,
            x_studio_asset_, x_studio_package_information, x_active,
            x_studio_value, x_studio_notes
        FROM x_demo_pool_tracking
        ORDER BY id
    """)
    rows = cr.fetchall()
    columns = [
        'id', 'x_name', 'equipment_type', 'wheelchair_category',
        'serial_number', 'seat_width', 'seat_depth',
        'seat_height', 'location', 'listing_type',
        'asset_number', 'package_info', 'active',
        'value', 'notes',
    ]

    created_count = 0
    serial_count = 0
    skipped_serials = 0
    errors = []

    print(f"\n{'='*60}")
    print("Demo Pool to Loaner Products Migration")
    print(f"{'='*60}")
    print(f"Records found: {len(rows)}")
    print()

    for row in rows:
        record = dict(zip(columns, row))
        demo_id = record['id']

        try:
            name = extract_name(record['x_name'])
            if not name:
                errors.append(f"ID {demo_id}: empty name, skipped")
                continue

            equipment_type_raw = record['equipment_type'] or ''
            equipment_type_key = EQUIPMENT_TYPE_MAP.get(equipment_type_raw, '')

            wheelchair_cat_raw = record['wheelchair_category'] or ''
            wheelchair_cat_key = WHEELCHAIR_CATEGORY_MAP.get(wheelchair_cat_raw, '')

            location_raw = record['location'] or ''
            location_key = LOCATION_MAP.get(location_raw, '')

            listing_raw = record['listing_type'] or ''
            listing_key = LISTING_TYPE_MAP.get(listing_raw, '')

            seat_width = (record['seat_width'] or '').strip()
            seat_depth = (record['seat_depth'] or '').strip()
            seat_height = (record['seat_height'] or '').strip()
            asset_number = (record['asset_number'] or '').strip()
            package_info = (record['package_info'] or '').strip()

            accessories = fetch_accessories(cr, demo_id)
            if accessories:
                acc_text = '\n'.join(f'- {a}' for a in accessories)
                if package_info:
                    package_info = f"{package_info}\n\nAccessories:\n{acc_text}"
                else:
                    package_info = f"Accessories:\n{acc_text}"

            is_active = bool(record['active'])
            categ_id = get_category_id(env, equipment_type_key)

            product_vals = {
                'name': name,
                'type': 'consu',
                'tracking': 'serial',
                'sale_ok': False,
                'purchase_ok': False,
                'x_fc_can_be_loaned': True,
                'x_fc_loaner_period_days': 7,
                'x_fc_equipment_type': equipment_type_key or False,
                'x_fc_wheelchair_category': wheelchair_cat_key or False,
                'x_fc_seat_width': seat_width or False,
                'x_fc_seat_depth': seat_depth or False,
                'x_fc_seat_height': seat_height or False,
                'x_fc_storage_location': location_key or False,
                'x_fc_listing_type': listing_key or False,
                'x_fc_asset_number': asset_number or False,
                'x_fc_package_info': package_info or False,
                'categ_id': categ_id,
                'active': is_active,
            }

            product = ProductTemplate.with_context(active_test=False).create(product_vals)
            created_count += 1

            serial_raw = (record['serial_number'] or '').strip()
            if serial_raw.lower() not in SKIP_SERIALS:
                try:
                    product_product = product.product_variant_id
                    if product_product:
                        lot = StockLot.create({
                            'name': serial_raw,
                            'product_id': product_product.id,
                            'company_id': company.id,
                        })
                        serial_count += 1
                except Exception as e:
                    skipped_serials += 1
                    errors.append(f"ID {demo_id} ({name}): serial '{serial_raw}' failed: {e}")
            else:
                skipped_serials += 1

            status = "ACTIVE" if is_active else "ARCHIVED"
            print(f"  [{status}] {name} (demo #{demo_id}) -> product #{product.id}"
                  f"{f' serial={serial_raw}' if serial_raw.lower() not in SKIP_SERIALS else ''}")

        except Exception as e:
            errors.append(f"ID {demo_id}: {e}")
            print(f"  ERROR: ID {demo_id}: {e}")

    env.cr.commit()

    print(f"\n{'='*60}")
    print("Migration Summary")
    print(f"{'='*60}")
    print(f"Products created:  {created_count}")
    print(f"Serials created:   {serial_count}")
    print(f"Serials skipped:   {skipped_serials}")
    print(f"Errors:            {len(errors)}")

    if errors:
        print(f"\nErrors:")
        for err in errors:
            print(f"  - {err}")

    print(f"\nDone. Verify in Fusion Claims > Loaner Management > Loaner Products")
    print(f"{'='*60}\n")


run_import(env)
