'use client';

import { useState, useRef } from 'react';
import { useRouter } from 'next/navigation';
import Link from 'next/link';
import { ArrowLeft, Camera, X } from 'lucide-react';
import { trpc } from '@/lib/trpc/client';

// Resize to max 1600px on longest side and compress to JPEG q=0.8.
function compressImage(file: File): Promise<Blob> {
  return new Promise((resolve, reject) => {
    const img = new Image();
    const url = URL.createObjectURL(file);
    img.onload = () => {
      URL.revokeObjectURL(url);
      const MAX = 1600;
      let { width, height } = img;
      if (width > MAX || height > MAX) {
        if (width >= height) {
          height = Math.round((height * MAX) / width);
          width = MAX;
        } else {
          width = Math.round((width * MAX) / height);
          height = MAX;
        }
      }
      const canvas = document.createElement('canvas');
      canvas.width = width;
      canvas.height = height;
      const ctx = canvas.getContext('2d');
      if (!ctx) return reject(new Error('Canvas context unavailable'));
      ctx.drawImage(img, 0, 0, width, height);
      canvas.toBlob(
        (blob) => (blob ? resolve(blob) : reject(new Error('Canvas toBlob failed'))),
        'image/jpeg',
        0.8,
      );
    };
    img.onerror = () => reject(new Error('Image load failed'));
    img.src = url;
  });
}

export default function NewRequestPage() {
  const router = useRouter();
  const fileRef = useRef<HTMLInputElement>(null);

  const [workstationId, setWorkstationId] = useState('');
  const [description, setDescription] = useState('');
  const [photoBlob, setPhotoBlob] = useState<Blob | null>(null);
  const [photoPreview, setPhotoPreview] = useState<string | null>(null);
  const [submitting, setSubmitting] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const { data: workstations = [], isLoading: wsLoading } = trpc.workstation.list.useQuery();
  const signUpload = trpc.storage.signPhotoUpload.useMutation();
  const createRequest = trpc.maintenanceRequest.create.useMutation();

  async function handlePhotoChange(e: React.ChangeEvent<HTMLInputElement>) {
    const file = e.target.files?.[0];
    if (!file) return;
    try {
      const compressed = await compressImage(file);
      if (photoPreview) URL.revokeObjectURL(photoPreview);
      const preview = URL.createObjectURL(compressed);
      setPhotoBlob(compressed);
      setPhotoPreview(preview);
    } catch {
      setError('Não foi possível processar a foto. Tenta de novo.');
    }
  }

  function removePhoto() {
    if (photoPreview) URL.revokeObjectURL(photoPreview);
    setPhotoBlob(null);
    setPhotoPreview(null);
    if (fileRef.current) fileRef.current.value = '';
  }

  async function handleSubmit(e: React.FormEvent) {
    e.preventDefault();
    if (!workstationId || description.trim().length < 3) return;

    setSubmitting(true);
    setError(null);

    try {
      const clientRequestId = crypto.randomUUID();
      let photoKey: string | undefined;

      // 1. Upload photo if present
      if (photoBlob) {
        const { uploadUrl, photoKey: key } = await signUpload.mutateAsync({
          contentType: 'image/jpeg',
          byteSize: photoBlob.size,
        });
        const res = await fetch(uploadUrl, {
          method: 'PUT',
          body: photoBlob,
          headers: { 'Content-Type': 'image/jpeg' },
        });
        if (!res.ok) throw new Error('Falha no upload da foto');
        photoKey = key;
      }

      // 2. Create request
      await createRequest.mutateAsync({
        workstationId,
        description: description.trim(),
        photoKey,
        clientRequestId,
      });

      // 3. Confirm
      router.push(`/maintenance/sent?cid=${clientRequestId}`);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Erro ao submeter pedido. Tenta de novo.');
      setSubmitting(false);
    }
  }

  const descLen = description.length;
  const canSubmit = workstationId !== '' && descLen >= 3 && descLen <= 1000 && !submitting;

  return (
    <main className="mx-auto flex min-h-dvh max-w-lg flex-col bg-background">
      {/* Header */}
      <header className="flex items-center gap-3 border-b border-border bg-card px-4 py-3">
        <Link href="/" className="rounded-md p-1 hover:bg-accent">
          <ArrowLeft className="h-5 w-5" />
        </Link>
        <h1 className="text-base font-semibold">Novo pedido de manutenção</h1>
      </header>

      <form onSubmit={handleSubmit} className="flex flex-1 flex-col gap-6 p-4">
        {/* Posto */}
        <div className="flex flex-col gap-1.5">
          <label htmlFor="workstation" className="text-sm font-medium">
            Posto <span className="text-destructive">*</span>
          </label>
          <select
            id="workstation"
            value={workstationId}
            onChange={(e) => setWorkstationId(e.target.value)}
            required
            disabled={wsLoading}
            className="w-full rounded-lg border border-border bg-card px-3 py-2.5 text-sm disabled:opacity-50"
          >
            <option value="">
              {wsLoading ? 'A carregar postos…' : 'Seleciona um posto…'}
            </option>
            {workstations.map((ws) => (
              <option key={ws.id} value={ws.id}>
                {ws.code} — {ws.name} · {ws.area}
              </option>
            ))}
          </select>
        </div>

        {/* Foto */}
        <div className="flex flex-col gap-1.5">
          <span className="text-sm font-medium">Foto (opcional)</span>
          {photoPreview ? (
            <div className="relative">
              {/* eslint-disable-next-line @next/next/no-img-element */}
              <img
                src={photoPreview}
                alt="Pré-visualização"
                className="h-48 w-full rounded-lg object-cover"
              />
              <button
                type="button"
                onClick={removePhoto}
                className="absolute right-2 top-2 rounded-full bg-black/60 p-1 text-white hover:bg-black/80"
              >
                <X className="h-4 w-4" />
              </button>
            </div>
          ) : (
            <button
              type="button"
              onClick={() => fileRef.current?.click()}
              className="flex h-24 w-full items-center justify-center gap-2 rounded-lg border-2 border-dashed border-border text-sm text-muted-foreground hover:bg-accent"
            >
              <Camera className="h-5 w-5" />
              Tirar / escolher foto
            </button>
          )}
          <input
            ref={fileRef}
            type="file"
            accept="image/*"
            capture="environment"
            className="hidden"
            onChange={handlePhotoChange}
          />
        </div>

        {/* Descrição */}
        <div className="flex flex-col gap-1.5">
          <label htmlFor="description" className="flex items-center justify-between text-sm font-medium">
            <span>
              Descrição <span className="text-destructive">*</span>
            </span>
            <span className={`text-xs ${descLen > 1000 ? 'text-destructive' : 'text-muted-foreground'}`}>
              {descLen}/1000
            </span>
          </label>
          <textarea
            id="description"
            value={description}
            onChange={(e) => setDescription(e.target.value)}
            required
            minLength={3}
            maxLength={1000}
            rows={4}
            placeholder="Descreve o problema…"
            className="w-full resize-none rounded-lg border border-border bg-card px-3 py-2.5 text-sm placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring"
          />
        </div>

        {error && (
          <p className="rounded-lg bg-destructive/10 px-3 py-2 text-sm text-destructive">{error}</p>
        )}

        <div className="mt-auto">
          <button
            type="submit"
            disabled={!canSubmit}
            className="w-full rounded-xl bg-primary px-6 py-4 text-base font-semibold text-primary-foreground transition-opacity hover:opacity-90 disabled:opacity-40"
          >
            {submitting ? 'A enviar…' : 'Enviar pedido'}
          </button>
        </div>
      </form>
    </main>
  );
}
