import {
  Controller,
  Get,
  Post,
  Put,
  Delete,
  Body,
  Param,
  HttpCode,
  HttpStatus,
  NotFoundException,
  BadRequestException,
  Logger,
} from '@nestjs/common'
import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger'
import { PrismaService } from '../../infrastructure/persistence/prisma/prisma.service'
import { ContactType } from '@prisma/client'

// ===== DTOs =====

interface CreateContactDto {
  type: string
  label: string
  value: string
  sortOrder: number
  isEnabled?: boolean
}

interface UpdateContactDto {
  type?: string
  label?: string
  value?: string
  sortOrder?: number
  isEnabled?: boolean
}

interface ContactResponseDto {
  id: string
  type: ContactType
  label: string
  value: string
  sortOrder: number
  isEnabled: boolean
  createdAt: Date
  updatedAt: Date
}

// =============================================================================
// Admin Controller (需要认证)
// =============================================================================

@ApiTags('Customer Service Contact Management')
@Controller('admin/customer-service-contacts')
export class AdminCustomerServiceContactController {
  private readonly logger = new Logger(AdminCustomerServiceContactController.name)

  constructor(private readonly prisma: PrismaService) {}

  @Get()
  @ApiBearerAuth()
  @ApiOperation({ summary: '查询客服联系方式列表 (全部)' })
  async list(): Promise<ContactResponseDto[]> {
    const contacts = await this.prisma.customerServiceContact.findMany({
      orderBy: [{ sortOrder: 'asc' }],
    })
    return contacts.map(this.toDto)
  }

  @Post()
  @ApiBearerAuth()
  @ApiOperation({ summary: '新增客服联系方式' })
  async create(@Body() body: CreateContactDto): Promise<ContactResponseDto> {
    const contactType = body.type as ContactType
    if (!Object.values(ContactType).includes(contactType)) {
      throw new BadRequestException(`Invalid type: ${body.type}. Must be WECHAT or QQ`)
    }
    if (!body.label || !body.value) {
      throw new BadRequestException('label and value are required')
    }
    if (body.sortOrder === undefined || body.sortOrder < 0) {
      throw new BadRequestException('sortOrder must be a non-negative integer')
    }

    const contact = await this.prisma.customerServiceContact.create({
      data: {
        type: contactType,
        label: body.label,
        value: body.value,
        sortOrder: body.sortOrder,
        isEnabled: body.isEnabled ?? true,
      },
    })

    this.logger.log(`Created customer service contact: id=${contact.id}, type=${contact.type}, label=${contact.label}`)
    return this.toDto(contact)
  }

  @Put(':id')
  @ApiBearerAuth()
  @HttpCode(HttpStatus.OK)
  @ApiOperation({ summary: '更新客服联系方式' })
  async update(
    @Param('id') id: string,
    @Body() body: UpdateContactDto,
  ): Promise<ContactResponseDto> {
    const existing = await this.prisma.customerServiceContact.findUnique({ where: { id } })
    if (!existing) {
      throw new NotFoundException('Contact not found')
    }

    const data: Record<string, unknown> = {}
    if (body.type !== undefined) {
      const contactType = body.type as ContactType
      if (!Object.values(ContactType).includes(contactType)) {
        throw new BadRequestException(`Invalid type: ${body.type}`)
      }
      data.type = contactType
    }
    if (body.label !== undefined) data.label = body.label
    if (body.value !== undefined) data.value = body.value
    if (body.sortOrder !== undefined) data.sortOrder = body.sortOrder
    if (body.isEnabled !== undefined) data.isEnabled = body.isEnabled

    const updated = await this.prisma.customerServiceContact.update({
      where: { id },
      data,
    })

    return this.toDto(updated)
  }

  @Delete(':id')
  @ApiBearerAuth()
  @HttpCode(HttpStatus.NO_CONTENT)
  @ApiOperation({ summary: '删除客服联系方式' })
  async delete(@Param('id') id: string): Promise<void> {
    const existing = await this.prisma.customerServiceContact.findUnique({ where: { id } })
    if (!existing) {
      throw new NotFoundException('Contact not found')
    }
    await this.prisma.customerServiceContact.delete({ where: { id } })
    this.logger.log(`Deleted customer service contact: id=${id}, type=${existing.type}`)
  }

  private toDto(contact: {
    id: string
    type: ContactType
    label: string
    value: string
    sortOrder: number
    isEnabled: boolean
    createdAt: Date
    updatedAt: Date
  }): ContactResponseDto {
    return {
      id: contact.id,
      type: contact.type,
      label: contact.label,
      value: contact.value,
      sortOrder: contact.sortOrder,
      isEnabled: contact.isEnabled,
      createdAt: contact.createdAt,
      updatedAt: contact.updatedAt,
    }
  }
}

// =============================================================================
// Public Controller (移动端调用，无需认证)
// =============================================================================

@ApiTags('Customer Service Contacts (Public)')
@Controller('customer-service-contacts')
export class PublicCustomerServiceContactController {
  constructor(private readonly prisma: PrismaService) {}

  @Get()
  @ApiOperation({ summary: '获取已启用的客服联系方式 (移动端)' })
  async list(): Promise<ContactResponseDto[]> {
    const contacts = await this.prisma.customerServiceContact.findMany({
      where: { isEnabled: true },
      orderBy: [{ sortOrder: 'asc' }],
    })

    return contacts.map((c) => ({
      id: c.id,
      type: c.type,
      label: c.label,
      value: c.value,
      sortOrder: c.sortOrder,
      isEnabled: c.isEnabled,
      createdAt: c.createdAt,
      updatedAt: c.updatedAt,
    }))
  }
}
