import { Injectable, NotFoundException, ConflictException } from '@nestjs/common';
import { PrismaService } from '@core/database/prisma/prisma.service';
import {
  CreateStationDto,
  UpdateStationDto,
  QueryStationDto,
  StationStatus,
  ImportStationItemDto,
} from '../dto/station.dto';
import { Prisma } from '@prisma/client';

@Injectable()
export class StationService {
  constructor(private readonly prisma: PrismaService) {}

  // 创建工位
  async create(dto: CreateStationDto) {
    // 检查代码是否已存在
    const existing = await this.prisma.station.findUnique({
      where: { code: dto.code },
    });

    if (existing) {
      throw new ConflictException(`工位代码 ${dto.code} 已存在`);
    }

    return this.prisma.station.create({
      data: {
        code: dto.code,
        nameEn: dto.nameEn,
        nameCn: dto.nameCn,
        description: dto.description,
        area: dto.area,
        line: dto.line,
        type: dto.type,
        status: dto.status || StationStatus.ACTIVE,
        sortOrder: dto.sortOrder || 0,
      },
    });
  }

  // 查询工位列表
  async findAll(query: QueryStationDto) {
    const {
      search,
      area,
      line,
      type,
      status,
      page = 1,
      limit = 20,
      sortBy = 'sortOrder',
      sortOrder = 'asc',
    } = query;

    const where: Prisma.StationWhereInput = {
      deletedAt: null,
    };

    // 搜索条件
    if (search) {
      where.OR = [
        { code: { contains: search, mode: 'insensitive' } },
        { nameEn: { contains: search, mode: 'insensitive' } },
        { nameCn: { contains: search, mode: 'insensitive' } },
      ];
    }

    // 筛选条件
    if (area) where.area = area;
    if (line) where.line = line;
    if (type) where.type = type;
    if (status) where.status = status;

    const [items, total] = await Promise.all([
      this.prisma.station.findMany({
        where,
        skip: (page - 1) * limit,
        take: limit,
        orderBy: { [sortBy]: sortOrder },
        include: {
          _count: {
            select: { parts: true },
          },
        },
      }),
      this.prisma.station.count({ where }),
    ]);

    return {
      items,
      total,
      page,
      limit,
      totalPages: Math.ceil(total / limit),
    };
  }

  // 获取单个工位
  async findOne(id: string) {
    const station = await this.prisma.station.findFirst({
      where: { id, deletedAt: null },
      include: {
        _count: {
          select: { parts: true },
        },
      },
    });

    if (!station) {
      throw new NotFoundException(`工位 ${id} 不存在`);
    }

    return station;
  }

  // 更新工位
  async update(id: string, dto: UpdateStationDto) {
    await this.findOne(id);

    // 如果更新代码，检查是否重复
    if (dto.code) {
      const existing = await this.prisma.station.findFirst({
        where: {
          code: dto.code,
          id: { not: id },
          deletedAt: null,
        },
      });

      if (existing) {
        throw new ConflictException(`工位代码 ${dto.code} 已存在`);
      }
    }

    return this.prisma.station.update({
      where: { id },
      data: dto,
    });
  }

  // 删除工位（软删除）
  async remove(id: string) {
    const station = await this.findOne(id);

    // 检查是否有关联的零件
    if (station._count.parts > 0) {
      throw new ConflictException(
        `工位 ${station.code} 下有 ${station._count.parts} 个零件，无法删除`,
      );
    }

    return this.prisma.station.update({
      where: { id },
      data: { deletedAt: new Date() },
    });
  }

  // 获取所有区域
  async getAreas() {
    const result = await this.prisma.station.findMany({
      where: { deletedAt: null, area: { not: null } },
      select: { area: true },
      distinct: ['area'],
    });

    return result.map((r) => r.area).filter(Boolean);
  }

  // 获取所有产线
  async getLines(area?: string) {
    const where: Prisma.StationWhereInput = {
      deletedAt: null,
      line: { not: null },
    };

    if (area) where.area = area;

    const result = await this.prisma.station.findMany({
      where,
      select: { line: true },
      distinct: ['line'],
    });

    return result.map((r) => r.line).filter(Boolean);
  }

  // 获取所有类型
  async getTypes() {
    const result = await this.prisma.station.findMany({
      where: { deletedAt: null, type: { not: null } },
      select: { type: true },
      distinct: ['type'],
    });

    return result.map((r) => r.type).filter(Boolean);
  }

  // 获取下拉选项
  async getSelectOptions() {
    return this.prisma.station.findMany({
      where: { deletedAt: null, status: StationStatus.ACTIVE },
      select: {
        id: true,
        code: true,
        nameEn: true,
        nameCn: true,
        area: true,
        line: true,
      },
      orderBy: [{ area: 'asc' }, { line: 'asc' }, { sortOrder: 'asc' }],
    });
  }

  // 获取导入模板
  getImportTemplate() {
    return [
      {
        code: 'ST-001',
        nameEn: 'Assembly Station 1',
        nameCn: '装配工位1',
        area: 'Workshop A',
        line: 'Line 1',
        type: 'Assembly',
        description: 'Main assembly station',
      },
    ];
  }

  // 批量导入
  async bulkImport(stations: ImportStationItemDto[]) {
    const results = {
      success: 0,
      failed: 0,
      errors: [] as { row: number; code: string; error: string }[],
      created: [] as any[],
    };

    for (let i = 0; i < stations.length; i++) {
      const station = stations[i];
      try {
        // 检查必填字段
        if (!station.code || !station.nameEn) {
          throw new Error('code 和 nameEn 为必填字段');
        }

        // 检查是否已存在
        const existing = await this.prisma.station.findUnique({
          where: { code: station.code },
        });

        if (existing) {
          // 如果已存在且未删除，跳过
          if (!existing.deletedAt) {
            throw new Error(`工位代码 ${station.code} 已存在`);
          }
          // 如果已删除，恢复并更新
          const updated = await this.prisma.station.update({
            where: { id: existing.id },
            data: {
              nameEn: station.nameEn,
              nameCn: station.nameCn,
              area: station.area,
              line: station.line,
              type: station.type,
              description: station.description,
              deletedAt: null,
              status: StationStatus.ACTIVE,
            },
          });
          results.created.push(updated);
        } else {
          // 创建新工位
          const created = await this.prisma.station.create({
            data: {
              code: station.code,
              nameEn: station.nameEn,
              nameCn: station.nameCn,
              area: station.area,
              line: station.line,
              type: station.type,
              description: station.description,
              status: StationStatus.ACTIVE,
            },
          });
          results.created.push(created);
        }

        results.success++;
      } catch (error) {
        results.failed++;
        results.errors.push({
          row: i + 1,
          code: station.code || `Row ${i + 1}`,
          error: error.message,
        });
      }
    }

    return results;
  }
}

