import { PageQuery } from '@/lib/contracts/page-queries/PageQuery';
import { Result } from '@/lib/contracts/Result';
import { TeamService } from '@/lib/services/teams/TeamService';
import { TeamDetailViewDataBuilder } from '@/lib/builders/view-data/TeamDetailViewDataBuilder';
import type { TeamDetailViewData } from '@/lib/view-data/TeamDetailViewData';
import { type PresentationError, mapToPresentationError } from '@/lib/contracts/page-queries/PresentationError';
import { SessionGateway } from '@/lib/gateways/SessionGateway';
import type { TeamMemberViewModel } from '@/lib/view-models/TeamMemberViewModel';

/**
 * TeamDetailPageDto - Raw serializable data for team detail page
 * Contains only raw data, no derived/computed properties
 */
export interface TeamDetailPageDto {
  team: {
    id: string;
    name: string;
    tag: string;
    description?: string;
    ownerId: string;
    leagues: string[];
    createdAt?: string;
    specialization?: string;
    region?: string;
    languages?: string[];
    category?: string;
    membership?: {
      role: string;
      joinedAt: string;
      isActive: boolean;
    } | null;
    canManage: boolean;
  };
  memberships: Array<{
    driverId: string;
    driverName: string;
    role: 'owner' | 'manager' | 'member';
    joinedAt: string;
    isActive: boolean;
    avatarUrl: string;
  }>;
  currentDriverId: string;
}

/**
 * TeamDetailPageQuery - Server-side composition for team detail page
 */
export class TeamDetailPageQuery implements PageQuery<TeamDetailViewData, string> {
  async execute(teamId: string): Promise<Result<TeamDetailViewData, PresentationError>> {
    // Get session to determine current driver (optional for public view)
    const sessionGateway = new SessionGateway();
    const session = await sessionGateway.getSession();
    
    const currentDriverId = session?.user?.primaryDriverId || '';
    const service = new TeamService();
    
    // Fetch team details
    const teamResult = await service.getTeamDetails(teamId, currentDriverId);
    
    if (teamResult.isErr()) {
      return Result.err(mapToPresentationError(teamResult.getError()));
    }

    const teamData = teamResult.unwrap();

    // Fetch team members
    const membersResult = await service.getTeamMembers(teamId, currentDriverId, teamData.team.ownerId);
    
    if (membersResult.isErr()) {
      return Result.err(mapToPresentationError(membersResult.getError()));
    }

    const membersData = membersResult.unwrap();
    
    // Transform to raw serializable DTO
    const dto: TeamDetailPageDto = {
      team: {
        id: teamData.team.id,
        name: teamData.team.name,
        tag: teamData.team.tag,
        description: teamData.team.description,
        ownerId: teamData.team.ownerId,
        leagues: teamData.team.leagues,
        createdAt: teamData.team.createdAt,
        specialization: (teamData.team as any).specialization,
        region: (teamData.team as any).region,
        languages: (teamData.team as any).languages,
        category: teamData.team.category,
        membership: teamData.membership ? {
          role: teamData.membership.role,
          joinedAt: teamData.membership.joinedAt,
          isActive: teamData.membership.isActive,
        } : null,
        canManage: teamData.canManage,
      },
      memberships: membersData.map((member: TeamMemberViewModel) => ({
        driverId: member.driverId,
        driverName: member.driverName,
        role: member.role,
        joinedAt: member.joinedAt,
        isActive: member.isActive,
        avatarUrl: member.avatarUrl,
      })),
      currentDriverId,
    };

    const viewData = TeamDetailViewDataBuilder.build(dto);
    return Result.ok(viewData);
  }

  static async execute(teamId: string): Promise<Result<TeamDetailViewData, PresentationError>> {
    const query = new TeamDetailPageQuery();
    return query.execute(teamId);
  }
}
