"""
Calendar Storage - Database models and operations
"""
from __future__ import annotations

import os
import logging
from datetime import datetime
from typing import Optional, List
from dataclasses import dataclass

logger = logging.getLogger(__name__)


# Simple SQLite-based storage (can be replaced with Postgres)
class CalendarStorage:
    """In-memory/SQLite storage for calendar accounts and reminders"""
    
    def __init__(self, db_session=None):
        self.db = db_session
        self._accounts = {}
        self._reminders = {}
        self._idempotency_keys = {}
        self._next_id = 1
    
    def create_account(
        self,
        workspace_id: str,
        user_id: str,
        provider: str,
        username: str,
        password: str,
        principal_url: str = None,
        default_calendar_id: str = None
    ):
        """Create calendar account"""
        # Check if exists
        for acc in self._accounts.values():
            if (acc.workspace_id == workspace_id and 
                acc.user_id == user_id and 
                acc.provider == provider):
                # Update
                acc.username = username
                acc.password = password
                acc.principal_url = principal_url
                acc.default_calendar_id = default_calendar_id
                acc.updated_at = datetime.utcnow()
                return acc
        
        # Create new
        account = CalendarAccount(
            id=f"acc_{self._next_id}",
            workspace_id=workspace_id,
            user_id=user_id,
            provider=provider,
            username=username,
            password=password,  # In production, encrypt this!
            principal_url=principal_url,
            default_calendar_id=default_calendar_id
        )
        
        self._accounts[account.id] = account
        self._next_id += 1
        
        logger.info(f"Created calendar account: {account.id}")
        
        return account
    
    def get_account(self, account_id: str) -> Optional[CalendarAccount]:
        """Get account by ID"""
        return self._accounts.get(account_id)
    
    def list_accounts(
        self,
        workspace_id: str,
        user_id: str
    ) -> List[CalendarAccount]:
        """List accounts for user"""
        return [
            acc for acc in self._accounts.values()
            if acc.workspace_id == workspace_id and acc.user_id == user_id
        ]
    
    def count_accounts(self) -> int:
        """Count total accounts"""
        return len(self._accounts)
    
    def create_reminder(
        self,
        workspace_id: str,
        user_id: str,
        account_id: str,
        event_uid: str,
        remind_at: str,
        channel: str = "inapp"
    ) -> "CalendarReminder":
        """Create reminder"""
        reminder = CalendarReminder(
            id=f"rem_{self._next_id}",
            workspace_id=workspace_id,
            user_id=user_id,
            account_id=account_id,
            event_uid=event_uid,
            remind_at=datetime.fromisoformat(remind_at),
            channel=channel,
            status="pending"
        )
        
        self._reminders[reminder.id] = reminder
        self._next_id += 1
        
        logger.info(f"Created reminder: {reminder.id}")
        
        return reminder
    
    def get_pending_reminders(self) -> List["CalendarReminder"]:
        """Get pending reminders"""
        now = datetime.utcnow()
        return [
            r for r in self._reminders.values()
            if r.status == "pending" and r.remind_at <= now
        ]
    
    def update_reminder_status(
        self,
        reminder_id: str,
        status: str,
        error: str = None
    ):
        """Update reminder status"""
        if reminder_id in self._reminders:
            self._reminders[reminder_id].status = status
            self._reminders[reminder_id].attempts += 1
            if error:
                self._reminders[reminder_id].last_error = error
    
    def count_pending_reminders(self) -> int:
        """Count pending reminders"""
        return len([r for r in self._reminders.values() if r.status == "pending"])
    
    def store_idempotency_key(
        self,
        key: str,
        workspace_id: str,
        user_id: str,
        event_uid: str
    ):
        """Store idempotency key"""
        self._idempotency_keys[key] = {
            "workspace_id": workspace_id,
            "user_id": user_id,
            "event_uid": event_uid
        }
    
    def get_by_idempotency_key(self, key: str) -> Optional[dict]:
        """Get event UID by idempotency key"""
        return self._idempotency_keys.get(key)


@dataclass
class CalendarAccount:
    """Calendar account model"""
    id: str
    workspace_id: str
    user_id: str
    provider: str
    username: str
    password: str
    principal_url: str = None
    default_calendar_id: str = None
    created_at: datetime = None
    updated_at: datetime = None
    
    def __post_init__(self):
        if self.created_at is None:
            self.created_at = datetime.utcnow()
        if self.updated_at is None:
            self.updated_at = datetime.utcnow()


@dataclass
class CalendarReminder:
    """Calendar reminder model"""
    id: str
    workspace_id: str
    user_id: str
    account_id: str
    event_uid: str
    remind_at: datetime
    channel: str
    status: str = "pending"
    attempts: int = 0
    last_error: str = None
    created_at: datetime = None
    
    def __post_init__(self):
        if self.created_at is None:
            self.created_at = datetime.utcnow()
