from __future__ import annotations

from datetime import datetime
from typing import NamedTuple
from peewee import CharField, FloatField, IntegerField, TimestampField
from defence360agent.model import instance, Model


class WPSite(NamedTuple):
    docroot: str
    domain: str
    uid: int
    version: str = "1.0.0"

    @classmethod
    def from_wordpress_site(cls, site: WordpressSite) -> WPSite:
        """Create a WPSite instance from a WordpressSite instance."""
        return cls(
            docroot=site.docroot,
            domain=site.domain,
            uid=site.uid,
            version=site.version,
        )

    def build_with_version(self, version: str) -> WPSite:
        """Create a new WPSite instance with an updated version."""
        return WPSite(
            docroot=self.docroot,
            domain=self.domain,
            uid=self.uid,
            version=version,
        )

    def __eq__(self, other):
        if not isinstance(other, WPSite):
            return NotImplemented
        # Ignore version and manually_deleted_at for equality check.
        return (self.docroot, self.domain, self.uid) == (
            other.docroot,
            other.domain,
            other.uid,
        )

    def __hash__(self):
        return hash((self.docroot, self.domain, self.uid))


class WPSiteRecord(NamedTuple):
    """A wordpress_site row as the repository hands it to callers.

    WPSite carries only what the install and update flows need. This adds
    manually_deleted_at for callers that report on removed sites, and keeps
    the peewee model itself out of repository return types so that columns
    added to the table are not exposed to the CLI by accident.
    """

    docroot: str
    domain: str
    uid: int
    version: str
    manually_deleted_at: datetime | None

    @classmethod
    def from_wordpress_site(cls, site: WordpressSite) -> WPSiteRecord:
        return cls(
            docroot=site.docroot,
            domain=site.domain,
            uid=site.uid,
            version=site.version,
            manually_deleted_at=site.manually_deleted_at,
        )

    def to_wpsite(self) -> WPSite:
        """Drop the flag: mutating helpers take a plain WPSite."""
        return WPSite(
            docroot=self.docroot,
            domain=self.domain,
            uid=self.uid,
            version=self.version,
        )


class WordpressSite(Model):
    class Meta:
        database = instance.db
        db_table = "wordpress_site"

    docroot = CharField(primary_key=True, null=False)
    domain = CharField(null=False)
    uid = IntegerField(null=False)
    manually_deleted_at = TimestampField(default=None, null=True)
    version = CharField(default="1.0.0", null=False)
    disabled_rules_sync_ts = FloatField(null=True, default=None)
