"""
CLI commands for issue activity tracking.

This module provides command-line interface for logging, viewing, and managing
issue activities for cost allocation and project management purposes.
"""

import click
from datetime import datetime, date
from typing import List, Optional
from tabulate import tabulate

from markitect.issues.activity_tracker import IssueActivityTracker, ActivityType, IssueActivity


@click.group()
def activity():
    """Issue activity tracking commands."""
    pass


@activity.command()
@click.argument('issue_id', type=int)
@click.argument('activity_type', type=click.Choice([at.value for at in ActivityType]))
@click.option('--date', '-d', type=click.DateTime(formats=['%Y-%m-%d']),
              help='Activity date (defaults to today)')
@click.option('--details', '-m', help='Activity details/message')
@click.option('--period-id', type=int, help='Cost period ID for allocation')
def log(issue_id: int, activity_type: str, date: Optional[datetime],
        details: Optional[str], period_id: Optional[int]):
    """Log an activity for an issue."""
    tracker = IssueActivityTracker()

    activity_date = date.date() if date else None
    activity_enum = ActivityType(activity_type)

    try:
        activity_id = tracker.log_activity(
            issue_id=issue_id,
            activity_type=activity_enum,
            activity_date=activity_date,
            activity_details=details,
            period_id=period_id
        )

        click.echo(f"✅ Logged {activity_type} activity for issue #{issue_id} (ID: {activity_id})")

        if details:
            click.echo(f"   Details: {details}")

    except Exception as e:
        click.echo(f"❌ Error logging activity: {e}", err=True)
        raise click.Abort()


@activity.command()
@click.argument('issue_id', type=int)
@click.option('--limit', '-l', type=int, default=20, help='Maximum number of activities to show')
@click.option('--offset', type=int, default=0, help='Number of activities to skip')
@click.option('--format', 'output_format', type=click.Choice(['table', 'json']),
              default='table', help='Output format')
def show(issue_id: int, limit: int, offset: int, output_format: str):
    """Show activities for a specific issue."""
    tracker = IssueActivityTracker()

    try:
        activities = tracker.get_issue_activities(issue_id, limit=limit, offset=offset)

        if not activities:
            click.echo(f"📝 No activities found for issue #{issue_id}")
            return

        if output_format == 'json':
            import json
            activity_data = [activity.to_dict() for activity in activities]
            click.echo(json.dumps(activity_data, indent=2))

        else:
            # Table format
            click.echo(f"\n📋 Activities for Issue #{issue_id}\n")

            headers = ['ID', 'Type', 'Date', 'Period', 'Details', 'Logged']
            rows = []

            for activity in activities:
                rows.append([
                    activity.id,
                    activity.activity_type_display,
                    activity.formatted_date,
                    activity.period_id or 'N/A',
                    activity.truncated_details,
                    activity.formatted_datetime
                ])

            click.echo(tabulate(rows, headers=headers, tablefmt='grid'))

            if len(activities) == limit:
                click.echo(f"\n💡 Showing {limit} most recent activities. Use --limit and --offset for pagination.")

    except Exception as e:
        click.echo(f"❌ Error retrieving activities: {e}", err=True)
        raise click.Abort()


@activity.command()
@click.option('--period-id', type=int, help='Filter by cost period ID')
@click.option('--activity-type', type=click.Choice([at.value for at in ActivityType]),
              multiple=True, help='Filter by activity types (can specify multiple)')
@click.option('--format', 'output_format', type=click.Choice(['table', 'json']),
              default='table', help='Output format')
def list(period_id: Optional[int], activity_type: List[str], output_format: str):
    """List activities across issues."""
    tracker = IssueActivityTracker()

    try:
        if period_id:
            activity_types = [ActivityType(at) for at in activity_type] if activity_type else None
            activities = tracker.get_activities_by_period(period_id, activity_types)
            title = f"Activities for Period #{period_id}"
        else:
            # For now, show recent activities across all issues (could be enhanced)
            click.echo("❌ Currently only period-based listing is supported. Use --period-id option.")
            return

        if not activities:
            click.echo(f"📝 No activities found for the specified criteria")
            return

        if output_format == 'json':
            import json
            activity_data = [activity.to_dict() for activity in activities]
            click.echo(json.dumps(activity_data, indent=2))

        else:
            # Table format
            click.echo(f"\n📊 {title}\n")

            headers = ['ID', 'Issue', 'Type', 'Date', 'Details']
            rows = []

            for activity in activities:
                rows.append([
                    activity.id,
                    f"#{activity.issue_id}",
                    activity.activity_type.value.title(),
                    activity.activity_date.strftime('%Y-%m-%d') if activity.activity_date else 'N/A',
                    (activity.activity_details[:50] + '...') if activity.activity_details and len(activity.activity_details) > 50 else (activity.activity_details or '')
                ])

            click.echo(tabulate(rows, headers=headers, tablefmt='grid'))
            click.echo(f"\n📈 Total: {len(activities)} activities")

    except Exception as e:
        click.echo(f"❌ Error retrieving activities: {e}", err=True)
        raise click.Abort()


@activity.command()
@click.option('--issue-id', type=int, help='Filter by specific issue ID')
@click.option('--start-date', type=click.DateTime(formats=['%Y-%m-%d']),
              help='Start date for summary period')
@click.option('--end-date', type=click.DateTime(formats=['%Y-%m-%d']),
              help='End date for summary period')
def summary(issue_id: Optional[int], start_date: Optional[datetime],
            end_date: Optional[datetime]):
    """Show activity summary statistics."""
    tracker = IssueActivityTracker()

    try:
        summary_data = tracker.get_activity_summary(
            issue_id=issue_id,
            start_date=start_date.date() if start_date else None,
            end_date=end_date.date() if end_date else None
        )

        click.echo("\n📊 Issue Activity Summary\n")

        # Basic stats
        click.echo(f"Total Activities: {summary_data['total_activities']}")
        click.echo(f"Unique Issues: {summary_data['unique_issues']}")

        # Date range
        date_range = summary_data['date_range']
        if date_range['start'] and date_range['end']:
            click.echo(f"Date Range: {date_range['start']} to {date_range['end']}")
        elif date_range['start']:
            click.echo(f"Since: {date_range['start']}")

        # Activity breakdown
        if summary_data['activities_by_type']:
            click.echo("\nActivity Breakdown:")
            for activity_type, count in summary_data['activities_by_type'].items():
                percentage = (count / summary_data['total_activities']) * 100
                click.echo(f"  {activity_type.title()}: {count} ({percentage:.1f}%)")

        # Filters applied
        filters = summary_data['filters']
        applied_filters = []
        if filters['issue_id']:
            applied_filters.append(f"Issue #{filters['issue_id']}")
        if filters['start_date']:
            applied_filters.append(f"From {filters['start_date']}")
        if filters['end_date']:
            applied_filters.append(f"Until {filters['end_date']}")

        if applied_filters:
            click.echo(f"\nFilters Applied: {', '.join(applied_filters)}")

    except Exception as e:
        click.echo(f"❌ Error generating summary: {e}", err=True)
        raise click.Abort()


@activity.command()
@click.argument('activity_id', type=int)
@click.confirmation_option(prompt='Are you sure you want to delete this activity?')
def delete(activity_id: int):
    """Delete an activity record."""
    tracker = IssueActivityTracker()

    try:
        if tracker.delete_activity(activity_id):
            click.echo(f"✅ Deleted activity #{activity_id}")
        else:
            click.echo(f"❌ Activity #{activity_id} not found")
            raise click.Abort()

    except Exception as e:
        click.echo(f"❌ Error deleting activity: {e}", err=True)
        raise click.Abort()


@activity.command()
@click.argument('file_path', type=click.Path(exists=True))
@click.option('--format', 'input_format', type=click.Choice(['json', 'csv']),
              default='json', help='Input file format')
def import_activities(file_path: str, input_format: str):
    """Import activities from a file."""
    tracker = IssueActivityTracker()

    try:
        if input_format == 'json':
            import json
            with open(file_path, 'r') as f:
                activities = json.load(f)

        elif input_format == 'csv':
            import csv
            activities = []
            with open(file_path, 'r') as f:
                reader = csv.DictReader(f)
                for row in reader:
                    activity = {
                        'issue_id': int(row['issue_id']),
                        'activity_type': row['activity_type'],
                        'activity_date': datetime.strptime(row['activity_date'], '%Y-%m-%d').date() if row.get('activity_date') else None,
                        'activity_details': row.get('activity_details'),
                        'period_id': int(row['period_id']) if row.get('period_id') else None
                    }
                    activities.append(activity)

        activity_ids = tracker.bulk_log_activities(activities)
        click.echo(f"✅ Successfully imported {len(activity_ids)} activities")

    except Exception as e:
        click.echo(f"❌ Error importing activities: {e}", err=True)
        raise click.Abort()


if __name__ == '__main__':
    activity()