import { Request, Response } from 'express';
import { prisma } from '../models';
import { LicenseStatus, PitStatus, Prisma } from '@prisma/client';
import { buildPitGuid } from '../lib/pit-guid';
import { writeAudit } from '../lib/audit';
import { QRGeneratorService } from '../services/qr-generator.service';
import { computeDaysRemaining } from '../lib/days-remaining';

export const pitController = {
  async listByLicense(req: Request, res: Response) {
    const { id: licenseId } = req.params;
    const pits = await prisma.pit.findMany({
      where: { license_id: licenseId, deleted_at: null },
      orderBy: { pit_number: 'asc' },
    });
    res.json({ success: true, data: { pits } });
  },

  async getOne(req: Request, res: Response) {
    const { id } = req.params;
    const pit = await prisma.pit.findFirst({
      where: { id, deleted_at: null },
      include: { license: true },
    });
    if (!pit) {
      res.status(404).json({ success: false, error: 'Pit not found' });
      return;
    }
    res.json({ success: true, data: pit });
  },

  async create(req: Request, res: Response) {
    const { id: licenseId } = req.params;
    const license = await prisma.license.findFirst({
      where: { id: licenseId, deleted_at: null },
    });
    if (!license) {
      res.status(404).json({ success: false, error: 'License not found' });
      return;
    }
    if (license.status !== LicenseStatus.ACTIVE) {
      res.status(400).json({ success: false, error: 'License must be ACTIVE to add pits' });
      return;
    }
    if (computeDaysRemaining(license.expiry_date) < 0) {
      res.status(400).json({ success: false, error: 'License is expired' });
      return;
    }

    const b = req.body as {
      pit_number: number;
      duara_number: number;
      pit_name?: string;
      gps_latitude: number;
      gps_longitude: number;
    };
    if (b.pit_number < 1 || b.pit_number > 40) {
      res.status(400).json({ success: false, error: 'pit_number must be 1-40' });
      return;
    }

    const pit_guid = buildPitGuid(license.license_type, license.license_number, b.pit_number, b.duara_number);
    const pitName = b.pit_name || `Pit ${b.pit_number}`;

    const qr = await QRGeneratorService.generatePitQRCode(pit_guid, pitName);
    const bc = await QRGeneratorService.generatePitBarcode(pit_guid);

    const pit = await prisma.pit.create({
      data: {
        pit_guid,
        pit_number: b.pit_number,
        duara_number: b.duara_number,
        pit_name: b.pit_name,
        license_id: licenseId,
        gps_latitude: b.gps_latitude,
        gps_longitude: b.gps_longitude,
        qr_code_url: qr,
        barcode_image_url: bc,
        status: PitStatus.ACTIVE,
        operational_access: true,
      },
    });

    await writeAudit(req, 'CREATE', 'Pit', pit.id, undefined, pit as unknown as Prisma.JsonValue);
    res.status(201).json({ success: true, data: pit });
  },

  async update(req: Request, res: Response) {
    const { id } = req.params;
    const existing = await prisma.pit.findFirst({ where: { id, deleted_at: null } });
    if (!existing) {
      res.status(404).json({ success: false, error: 'Not found' });
      return;
    }
    const b = req.body as Record<string, unknown>;
    const data: Prisma.PitUpdateInput = {};
    if (b.pit_name != null) data.pit_name = String(b.pit_name);
    if (b.gps_latitude != null) data.gps_latitude = Number(b.gps_latitude);
    if (b.gps_longitude != null) data.gps_longitude = Number(b.gps_longitude);
    if (b.status != null) data.status = b.status as PitStatus;
    if (b.operational_access != null) data.operational_access = Boolean(b.operational_access);

    const updated = await prisma.pit.update({ where: { id }, data });
    await writeAudit(req, 'UPDATE', 'Pit', id, existing as unknown as Prisma.JsonValue, updated as unknown as Prisma.JsonValue);
    res.json({ success: true, data: updated });
  },

  async softDelete(req: Request, res: Response) {
    const { id } = req.params;
    await prisma.pit.update({
      where: { id },
      data: { deleted_at: new Date(), deleted_by: req.user!.id },
    });
    await writeAudit(req, 'DELETE', 'Pit', id);
    res.json({ success: true, message: 'Pit soft-deleted' });
  },

  async generateQr(req: Request, res: Response) {
    const { id } = req.params;
    const pit = await prisma.pit.findFirst({ where: { id, deleted_at: null }, include: { license: true } });
    if (!pit) {
      res.status(404).json({ success: false, error: 'Not found' });
      return;
    }
    const pitName = pit.pit_name || pit.pit_guid;
    const qr = await QRGeneratorService.generatePitQRCode(pit.pit_guid, pitName);
    const bc = await QRGeneratorService.generatePitBarcode(pit.pit_guid);
    const updated = await prisma.pit.update({
      where: { id },
      data: { qr_code_url: qr, barcode_image_url: bc },
    });
    res.json({ success: true, data: updated });
  },

  async scanByGuid(req: Request, res: Response) {
    const { guid } = req.params;
    const pit = await prisma.pit.findFirst({
      where: { pit_guid: guid, deleted_at: null },
      include: { license: true },
    });
    if (!pit) {
      res.status(404).json({ success: false, error: 'Invalid pit GUID' });
      return;
    }
    res.json({ success: true, data: pit });
  },
};
