from __future__ import annotations

import subprocess
from dataclasses import asdict
from datetime import date, datetime, timedelta
from typing import Any

from .models import ReminderPlan
from .query import select_due_fields


def build_birthday_plans(customers: list[dict[str, Any]]) -> list[ReminderPlan]:
    plans: list[ReminderPlan] = []
    for customer in customers:
        birthday = customer.get("birthday")
        if not birthday:
            continue
        try:
            month = int(birthday.split("-")[1])
            day = int(birthday.split("-")[2])
        except (IndexError, ValueError):
            continue
        cron_expr = f"0 9 {day} {month} *"
        plans.append(
            ReminderPlan(
                customer_id=customer["customer_id"],
                customer_name=customer["name"],
                reminder_type="birthday",
                title=f"{customer['name']} 生日提醒",
                trigger_at=None,
                cron_expr=cron_expr,
                message=f"🎂 客户 {customer['name']} 今天生日，记得送上祝福或做一次回访。",
                recurring=True,
            )
        )
    return plans


def build_due_plans(customers: list[dict[str, Any]], *, days: tuple[int, ...] = (30, 7, 1)) -> list[ReminderPlan]:
    today = date.today()
    plans: list[ReminderPlan] = []
    for customer in customers:
        for item in select_due_fields(customer):
            due_date = date.fromisoformat(item["date"])
            for before_days in days:
                trigger_date = due_date - timedelta(days=before_days)
                if trigger_date < today:
                    continue
                cron_expr = f"0 9 {trigger_date.day} {trigger_date.month} *"
                plans.append(
                    ReminderPlan(
                        customer_id=customer["customer_id"],
                        customer_name=customer["name"],
                        reminder_type="due_date",
                        title=f"{customer['name']} {item['label']}提醒",
                        trigger_at=trigger_date.isoformat(),
                        cron_expr=cron_expr,
                        message=(
                            f"⏰ 客户 {customer['name']} 的「{item['label']}」将在 {before_days} 天后到来，"
                            f"当前记录日期为 {item['display_value']}。"
                        ),
                        recurring=False,
                    )
                )
    return plans


def build_follow_up_plan(customer: dict[str, Any], follow_up_date: str) -> ReminderPlan:
    due_date = date.fromisoformat(follow_up_date)
    cron_expr = f"0 9 {due_date.day} {due_date.month} *"
    return ReminderPlan(
        customer_id=customer["customer_id"],
        customer_name=customer["name"],
        reminder_type="follow_up",
        title=f"{customer['name']} 跟进提醒",
        trigger_at=follow_up_date,
        cron_expr=cron_expr,
        message=f"📞 记得跟进客户 {customer['name']}。",
        recurring=False,
    )


def schedule_plans(plans: list[ReminderPlan], *, tz: str = "Asia/Shanghai") -> list[dict[str, Any]]:
    results = []
    for plan in plans:
        task_name = _build_task_name(plan)
        command = [
            "openclaw",
            "cron",
            "add",
            "--name",
            task_name,
            "--cron",
            plan.cron_expr,
            "--tz",
            tz,
            "--session",
            "main",
            "--system-event",
            plan.message,
        ]
        if not plan.recurring:
            command.append("--delete-after-run")

        process = subprocess.run(command, capture_output=True, text=True)
        results.append(
            {
                **asdict(plan),
                "task_name": task_name,
                "scheduled": process.returncode == 0,
                "stdout": process.stdout.strip(),
                "stderr": process.stderr.strip(),
            }
        )
    return results


def _build_task_name(plan: ReminderPlan) -> str:
    timestamp = plan.trigger_at or datetime.now().date().isoformat()
    safe_name = "".join(char if char.isalnum() else "_" for char in plan.customer_name)[:24]
    return f"customer-{plan.reminder_type}-{timestamp}-{safe_name}"
