import base64
import hashlib
import json
import logging

import requests

from odoo import fields, models

_logger = logging.getLogger(__name__)


class WooProductMap(models.Model):
    _name = 'woo.product.map'
    _description = 'WooCommerce Product Mapping'

    instance_id = fields.Many2one('woo.instance', required=True, ondelete='cascade')
    product_id = fields.Many2one('product.product')
    woo_product_id = fields.Integer()
    woo_product_name = fields.Char()
    woo_sku = fields.Char()
    woo_product_type = fields.Selection([
        ('simple', 'Simple'),
        ('variable', 'Variable'),
        ('grouped', 'Grouped'),
        ('external', 'External'),
    ])
    woo_price = fields.Float(string='WC Price', digits='Product Price')
    woo_parent_id = fields.Integer()
    is_variation = fields.Boolean()
    sync_price = fields.Boolean(default=True)
    sync_inventory = fields.Boolean(default=True)
    sync_images = fields.Boolean(default=True)
    woo_image_ids = fields.Char()  # JSON
    last_synced = fields.Datetime()
    company_id = fields.Many2one(
        'res.company', required=True, default=lambda self: self.env.company,
    )
    state = fields.Selection([
        ('unmapped', 'Unmapped'),
        ('mapped', 'Mapped'),
        ('conflict', 'Conflict'),
        ('error', 'Error'),
    ], default='unmapped')

    # ------------------------------------------------------------------
    # Individual Price Sync
    # ------------------------------------------------------------------

    def action_push_price_to_odoo(self):
        """Update Odoo product price from WC price."""
        for rec in self:
            if rec.product_id and rec.woo_price:
                rec.product_id.list_price = rec.woo_price
                rec.instance_id._log_sync(
                    'product', 'woo_to_odoo', rec.product_id.name, 'success',
                    'Price updated from WC: $%.2f' % rec.woo_price,
                )

    def action_push_price_to_wc(self):
        """Update WC product price from Odoo price."""
        for rec in self:
            if rec.product_id and rec.instance_id:
                client = rec.instance_id._get_client()
                new_price = str(rec.product_id.list_price)
                client.update_product(rec.woo_product_id, {'regular_price': new_price})
                rec.woo_price = rec.product_id.list_price
                rec.instance_id._log_sync(
                    'product', 'odoo_to_woo', rec.product_id.name, 'success',
                    'Price pushed to WC: $%.2f' % rec.product_id.list_price,
                )

    # ------------------------------------------------------------------
    # Image Sync (Task 22)
    # ------------------------------------------------------------------

    def action_sync_images(self):
        """Sync product images between Odoo and WooCommerce."""
        for pm in self:
            if not pm.sync_images or not pm.product_id or pm.state != 'mapped':
                continue
            try:
                pm._sync_images_single()
            except Exception as e:
                _logger.error(
                    "Image sync failed for %s (WC#%s): %s",
                    pm.product_id.display_name, pm.woo_product_id, e,
                )

    def _sync_images_single(self):
        """Sync images for a single product mapping."""
        self.ensure_one()
        client = self.instance_id._get_client()
        wc_product = client.get_product(self.woo_product_id)
        wc_images = wc_product.get('images', [])

        # Get Odoo product image hash
        odoo_image = self.product_id.image_1920
        odoo_hash = ''
        if odoo_image:
            odoo_hash = hashlib.md5(base64.b64decode(odoo_image)).hexdigest()

        # Get WC image hash (download first image)
        wc_hash = ''
        wc_image_url = ''
        if wc_images:
            wc_image_url = wc_images[0].get('src', '')
            if wc_image_url:
                try:
                    resp = requests.get(wc_image_url, timeout=15)
                    if resp.status_code == 200:
                        wc_hash = hashlib.md5(resp.content).hexdigest()
                except Exception:
                    pass

        # Compare
        if odoo_hash and wc_hash and odoo_hash == wc_hash:
            # Images match — nothing to do
            return

        if odoo_image and not wc_images:
            # Push Odoo image to WC
            image_data = base64.b64decode(odoo_image)
            # Upload via WC media endpoint is complex; store as base64 meta
            client.update_product(self.woo_product_id, {
                'images': [{'src': '', 'name': self.product_id.name}],
            })
            _logger.info("Image push for %s — WC images updated", self.product_id.display_name)

        elif wc_images and not odoo_image:
            # Pull WC image to Odoo
            if wc_image_url:
                try:
                    resp = requests.get(wc_image_url, timeout=15)
                    if resp.status_code == 200:
                        self.product_id.image_1920 = base64.b64encode(resp.content)
                except Exception as e:
                    _logger.warning("Failed to download WC image: %s", e)

        # Store WC image IDs for reference
        image_ids = [{'id': img.get('id'), 'src': img.get('src', '')} for img in wc_images]
        self.woo_image_ids = json.dumps(image_ids)
        self.last_synced = fields.Datetime.now()
