'use client';

import { useEffect, useMemo, useState } from 'react';
import { useParams, useRouter } from 'next/navigation';
import Link from 'next/link';
import {
  ArrowLeft,
  Banknote,
  Briefcase,
  CalendarDays,
  CheckCircle2,
  Clock,
  FileText,
  ImageIcon,
  Loader2,
  MapPin,
  MessageCircle,
  MessageSquare,
  Sparkles,
  UserRound,
} from 'lucide-react';
import { DashboardLayout } from '@/components/layout/DashboardLayout';
import { JobLocationMap } from '@/components/map/JobLocationMap';
import { JobProgressPanel } from '@/components/jobs/JobProgressPanel';
import { JobCommentsSection } from '@/components/jobs/JobCommentsSection';
import { JobStatusTimeline } from '@/components/jobs/JobStatusTimeline';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Card, CardContent } from '@/components/ui/card';
import { Input } from '@/components/ui/input';
import { UserAvatar } from '@/components/ui/UserAvatar';
import {
  SectionTitle,
  WorkerPortalLoading,
  WorkerPortalSection,
  WorkerPortalShell,
} from '@/components/worker/WorkerPortal';
import { useAuth } from '@/contexts/AuthContext';
import { api, getUploadUrl } from '@/lib/api';
import { buildJobMessagesHref, stashPendingJobMessage } from '@/lib/jobContextMessage';
import { cn, formatCurrency, formatDate, formatRelativeTime } from '@/lib/utils';
import {
  JOB_STATUS_LABELS,
  QUOTATION_STATUS_LABELS,
  type JobStatus,
  type QuotationStatus,
} from '@ehandyhire/shared';

interface JobImage {
  id: string;
  url: string;
}

interface JobPerson {
  firstName: string;
  lastName: string;
  avatarUrl?: string | null;
}

interface JobQuotation {
  id: string;
  workerId: string;
  amount: number | string;
  status: QuotationStatus;
  message?: string | null;
  createdAt: string;
}

interface WorkerJobDetail {
  id: string;
  title: string;
  description: string;
  location: string;
  latitude: number | null;
  longitude: number | null;
  status: JobStatus;
  budget?: number | string | null;
  createdAt: string;
  dateNeeded?: string | null;
  workerId?: string | null;
  invitedWorkerId?: string | null;
  workerMarkedCompleteAt?: string | null;
  category?: { name: string };
  customer?: JobPerson | null;
  images?: JobImage[];
  quotations?: JobQuotation[];
}

function statusBadgeVariant(status: JobStatus) {
  switch (status) {
    case 'OPEN':
      return 'success' as const;
    case 'QUOTED':
      return 'warning' as const;
    case 'COMPLETED':
      return 'secondary' as const;
    case 'CANCELLED':
      return 'destructive' as const;
    default:
      return 'default' as const;
  }
}

function MetaItem({
  icon: Icon,
  label,
  value,
  highlight,
}: {
  icon: React.ComponentType<{ className?: string }>;
  label: string;
  value: string;
  highlight?: boolean;
}) {
  return (
    <div className="min-w-0">
      <p className="text-[11px] font-semibold uppercase tracking-wide text-muted">{label}</p>
      <p
        className={cn(
          'mt-0.5 flex items-center gap-1.5 text-sm font-medium text-slate-900',
          highlight && 'text-accent'
        )}
      >
        <Icon className={cn('h-4 w-4 shrink-0', highlight ? 'text-accent' : 'text-slate-400')} />
        <span className="truncate">{value}</span>
      </p>
    </div>
  );
}

function CustomerCard({
  customer,
  jobId,
  messagesHref,
  messageDraft,
  onMessageDraftChange,
}: {
  customer: JobPerson;
  jobId: string;
  messagesHref: string;
  messageDraft: string;
  onMessageDraftChange: (value: string) => void;
}) {
  const router = useRouter();
  const name = `${customer.firstName} ${customer.lastName}`;

  const handleMessageCustomer = () => {
    stashPendingJobMessage(jobId, messageDraft);
    router.push(messagesHref);
  };

  return (
    <WorkerPortalSection icon={UserRound} title="Customer" description="Posted this job">
      <div className="flex items-center gap-3">
        <UserAvatar
          firstName={customer.firstName}
          lastName={customer.lastName}
          avatarUrl={customer.avatarUrl}
          size="sm"
        />
        <div className="min-w-0 flex-1">
          <p className="font-semibold text-slate-900">{name}</p>
          <p className="text-sm text-muted">Job poster</p>
        </div>
      </div>
      <div className="mt-4 space-y-3">
        <div>
          <label htmlFor={`customer-message-${jobId}`} className="text-sm font-medium text-slate-700">
            Your message
          </label>
          <textarea
            id={`customer-message-${jobId}`}
            value={messageDraft}
            onChange={(e) => onMessageDraftChange(e.target.value)}
            rows={3}
            className="form-textarea mt-1.5 w-full resize-y"
            placeholder="Ask a question or introduce yourself before messaging…"
          />
        </div>
        <Button
          type="button"
          variant="outline"
          className="w-full gap-2"
          onClick={handleMessageCustomer}
        >
          <MessageCircle className="h-4 w-4" />
          Message customer
        </Button>
      </div>
    </WorkerPortalSection>
  );
}

export default function WorkerJobDetailPage() {
  const { id } = useParams<{ id: string }>();
  const { user, isLoading: authLoading } = useAuth();
  const [job, setJob] = useState<WorkerJobDetail | null>(null);
  const [pageLoading, setPageLoading] = useState(true);
  const [submitting, setSubmitting] = useState(false);
  const [withdrawing, setWithdrawing] = useState(false);
  const [submitError, setSubmitError] = useState('');
  const [customerMessage, setCustomerMessage] = useState('');
  const [applicationForm, setApplicationForm] = useState({ amount: '', message: '' });

  const workerProfileId = user?.workerProfile?.id as string | undefined;

  useEffect(() => {
    if (!id || authLoading) return;
    setPageLoading(true);
    api<{ data: WorkerJobDetail }>(`/jobs/${id}`)
      .then((res) => {
        setJob(res.data);
      })
      .catch(console.error)
      .finally(() => setPageLoading(false));
  }, [id, workerProfileId, authLoading]);

  const myQuotation = useMemo(
    () => (job?.quotations ?? []).find((q) => q.workerId === workerProfileId),
    [job?.quotations, workerProfileId]
  );

  useEffect(() => {
    if (job?.budget != null && Number(job.budget) > 0) {
      setApplicationForm((prev) => ({
        ...prev,
        amount: prev.amount || String(Number(job.budget)),
      }));
    }
  }, [job?.budget]);

  const reloadJob = async () => {
    const res = await api<{ data: WorkerJobDetail }>(`/jobs/${id}`);
    setJob(res.data);
  };

  const handleSubmitApplication = async (e: React.FormEvent) => {
    e.preventDefault();
    const amount = parseFloat(applicationForm.amount);
    if (!amount || amount <= 0) {
      setSubmitError('Enter a valid offer amount');
      return;
    }
    setSubmitting(true);
    setSubmitError('');
    try {
      await api('/quotations', {
        method: 'POST',
        body: JSON.stringify({
          jobId: id,
          amount,
          message: applicationForm.message.trim() || undefined,
        }),
      });
      await reloadJob();
    } catch (err: unknown) {
      setSubmitError(err instanceof Error ? err.message : 'Failed to submit application');
    } finally {
      setSubmitting(false);
    }
  };

  const handleWithdrawApplication = async () => {
    if (!myQuotation) return;
    setWithdrawing(true);
    setSubmitError('');
    try {
      await api(`/quotations/${myQuotation.id}/withdraw`, { method: 'PATCH' });
      await reloadJob();
    } catch (err: unknown) {
      setSubmitError(err instanceof Error ? err.message : 'Failed to withdraw application');
    } finally {
      setWithdrawing(false);
    }
  };

  if (pageLoading || authLoading || !job) {
    return (
      <DashboardLayout role="worker" title="Job details">
        <WorkerPortalShell width="wide">
          <WorkerPortalLoading label="Loading job…" />
        </WorkerPortalShell>
      </DashboardLayout>
    );
  }

  const status = job.status;
  const isAssigned = workerProfileId != null && job.workerId === workerProfileId;
  const showProgress = isAssigned && ['ACCEPTED', 'IN_PROGRESS', 'COMPLETED'].includes(status);
  const hasPendingApplication = myQuotation?.status === 'PENDING';
  const quoteCount = job.quotations?.length ?? 0;
  const images = job.images ?? [];
  const messagesHref = buildJobMessagesHref('worker', id);
  const backHref = isAssigned ? '/worker/accepted' : '/worker/jobs';
  const backLabel = isAssigned ? 'Accepted jobs' : 'Available jobs';

  return (
    <DashboardLayout role="worker" title={job.title}>
      <WorkerPortalShell width="wide">
        <Link
          href={backHref}
          className="inline-flex items-center gap-1.5 text-sm font-medium text-muted transition-colors hover:text-primary"
        >
          <ArrowLeft className="h-4 w-4" />
          Back to {backLabel}
        </Link>

        <Card>
          <CardContent className="p-5 sm:p-6">
            <div className="flex flex-wrap items-center gap-2">
              {job.category?.name ? (
                <Badge variant="secondary" className="normal-case tracking-normal">
                  {job.category.name}
                </Badge>
              ) : null}
              <Badge variant={statusBadgeVariant(status)} className="normal-case tracking-normal">
                {JOB_STATUS_LABELS[status]}
              </Badge>
            </div>

            <h1 className="mt-3 text-2xl font-bold leading-tight text-slate-900 sm:text-3xl">
              {job.title}
            </h1>

            <div className="mt-5 grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
              <MetaItem icon={MapPin} label="Location" value={job.location} />
              <MetaItem
                icon={Banknote}
                label="Budget"
                value={
                  job.budget != null && Number(job.budget) > 0
                    ? formatCurrency(Number(job.budget))
                    : 'Negotiable'
                }
                highlight={job.budget != null && Number(job.budget) > 0}
              />
              <MetaItem
                icon={Clock}
                label="Posted"
                value={formatRelativeTime(job.createdAt)}
              />
              {job.dateNeeded ? (
                <MetaItem
                  icon={CalendarDays}
                  label="Needed by"
                  value={formatDate(job.dateNeeded)}
                />
              ) : (
                <MetaItem icon={MessageSquare} label="Applications" value={`${quoteCount} on job`} />
              )}
            </div>
          </CardContent>
        </Card>

        {showProgress ? (
          <div className="space-y-4">
            <JobStatusTimeline status={status} workerMarkedCompleteAt={job.workerMarkedCompleteAt} />
            <JobProgressPanel
              jobId={id}
              status={status}
              role="worker"
              workerMarkedCompleteAt={job.workerMarkedCompleteAt}
              onUpdated={(updated) =>
                setJob((prev) => (prev ? { ...prev, ...updated } : prev))
              }
            />
          </div>
        ) : null}

        <div className="grid gap-6 lg:grid-cols-[minmax(0,1fr)_min(320px,34%)] lg:items-start">
          <div className="space-y-6">
            <WorkerPortalSection
              icon={FileText}
              title="Job description"
              description="What the customer needs done"
            >
              <p className="whitespace-pre-wrap leading-relaxed text-slate-600">{job.description}</p>
            </WorkerPortalSection>

            {images.length > 0 ? (
              <WorkerPortalSection icon={ImageIcon} title="Photos" description="Reference images from the customer">
                <div className="grid grid-cols-2 gap-3 sm:grid-cols-3">
                  {images.map((img) => (
                    <a
                      key={img.id}
                      href={getUploadUrl(img.url)}
                      target="_blank"
                      rel="noopener noreferrer"
                      className="block overflow-hidden rounded-xl border border-border bg-slate-100"
                    >
                      {/* eslint-disable-next-line @next/next/no-img-element */}
                      <img
                        src={getUploadUrl(img.url)}
                        alt=""
                        className="aspect-square w-full object-cover transition-transform hover:scale-[1.02]"
                      />
                    </a>
                  ))}
                </div>
              </WorkerPortalSection>
            ) : null}

            <WorkerPortalSection icon={MapPin} title="Location" description="Where the job takes place">
              <JobLocationMap
                job={{
                  id: job.id,
                  title: job.title,
                  location: job.location,
                  latitude: job.latitude,
                  longitude: job.longitude,
                }}
              />
            </WorkerPortalSection>

            <JobCommentsSection jobId={id} variant="worker" />
          </div>

          <aside className="space-y-6 lg:sticky lg:top-20">
            {job.customer ? (
              <CustomerCard
                customer={job.customer}
                jobId={id}
                messagesHref={messagesHref}
                messageDraft={customerMessage}
                onMessageDraftChange={setCustomerMessage}
              />
            ) : null}

            {hasPendingApplication && myQuotation ? (
              <WorkerPortalSection
                icon={Sparkles}
                title="Your application"
                description="Waiting for the customer to review your offer"
              >
                <div className="space-y-3">
                  <p className="text-2xl font-bold text-accent">
                    {formatCurrency(Number(myQuotation.amount))}
                  </p>
                  {myQuotation.message ? (
                    <p className="text-sm text-slate-600 whitespace-pre-wrap">{myQuotation.message}</p>
                  ) : null}
                  {submitError ? <p className="text-sm text-red-500">{submitError}</p> : null}
                  <Button
                    variant="outline"
                    className="w-full"
                    disabled={withdrawing}
                    onClick={handleWithdrawApplication}
                  >
                    {withdrawing ? 'Withdrawing…' : 'Withdraw application'}
                  </Button>
                </div>
              </WorkerPortalSection>
            ) : null}

            {myQuotation && myQuotation.status !== 'PENDING' && !isAssigned ? (
              <Card className="border-slate-200 bg-slate-50">
                <CardContent className="p-5 text-center text-sm text-muted">
                  Application status:{' '}
                  <span className="font-semibold text-slate-800">
                    {QUOTATION_STATUS_LABELS[myQuotation.status]}
                  </span>
                </CardContent>
              </Card>
            ) : null}

            {!myQuotation && !isAssigned && ['OPEN', 'QUOTED'].includes(status) ? (
              <WorkerPortalSection
                icon={Sparkles}
                title="Apply for this job"
                description="Send your offer to the customer"
              >
                <form onSubmit={handleSubmitApplication} className="space-y-3">
                  <Input
                    label="Your offer (PHP)"
                    type="number"
                    min="1"
                    step="0.01"
                    value={applicationForm.amount}
                    onChange={(e) =>
                      setApplicationForm((prev) => ({ ...prev, amount: e.target.value }))
                    }
                    required
                  />
                  <div>
                    <label className="text-sm font-medium text-slate-700">Message (optional)</label>
                    <textarea
                      value={applicationForm.message}
                      onChange={(e) =>
                        setApplicationForm((prev) => ({ ...prev, message: e.target.value }))
                      }
                      rows={3}
                      className="form-textarea mt-1.5 w-full resize-y"
                      placeholder="Briefly explain your experience or availability…"
                    />
                  </div>
                  {submitError ? <p className="text-sm text-red-500">{submitError}</p> : null}
                  <Button type="submit" className="w-full gap-2" disabled={submitting}>
                    {submitting ? (
                      <>
                        <Loader2 className="h-4 w-4 animate-spin" />
                        Submitting…
                      </>
                    ) : (
                      <>
                        <CheckCircle2 className="h-4 w-4" />
                        Submit application
                      </>
                    )}
                  </Button>
                </form>
              </WorkerPortalSection>
            ) : null}

            {status === 'COMPLETED' && isAssigned ? (
              <Card className="border-emerald-200 bg-emerald-50">
                <CardContent className="p-5 text-center">
                  <div className="mx-auto mb-3 flex h-12 w-12 items-center justify-center rounded-full bg-emerald-100 text-emerald-600">
                    <Briefcase className="h-6 w-6" />
                  </div>
                  <h2 className="font-bold text-emerald-900">Job completed</h2>
                  <p className="mt-1 text-sm text-emerald-800">
                    The customer confirmed this job is done. Great work!
                  </p>
                </CardContent>
              </Card>
            ) : null}

            {!isAssigned && !showProgress && !['OPEN', 'QUOTED'].includes(status) ? (
              <Card>
                <CardContent className="p-5 text-center text-sm text-muted">
                  This job is no longer accepting applications.
                </CardContent>
              </Card>
            ) : null}
          </aside>
        </div>
      </WorkerPortalShell>
    </DashboardLayout>
  );
}
