'use client';

import { useEffect, useState } from 'react';
import { useParams, useRouter } from 'next/navigation';
import Link from 'next/link';
import {
  ArrowLeft,
  Banknote,
  Briefcase,
  CalendarDays,
  CheckCircle2,
  Clock,
  FileText,
  ImageIcon,
  MapPin,
  MessageCircle,
  MessageSquare,
  Send,
  Star,
  UserRound,
  XCircle,
} from 'lucide-react';
import { DashboardLayout } from '@/components/layout/DashboardLayout';
import { HireDisclaimerModal } from '@/components/legal/HireDisclaimerModal';
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 { ReviewForm } from '@/components/reviews/ReviewForm';
import { StarRating } from '@/components/reviews/StarRating';
import { SaveWorkerButton } from '@/components/workers/SaveWorkerButton';
import { UserAvatar } from '@/components/ui/UserAvatar';
import {
  PortalLoading,
  PortalSection,
  PortalShell,
} from '@/components/portal/Portal';
import { buildJobMessagesHref } from '@/lib/jobContextMessage';
import { api, getUploadUrl } from '@/lib/api';
import { buildCreateJobUrl } from '@/lib/createJob';
import {
  cn,
  formatCurrency,
  formatDate,
  formatRelativeTime,
} from '@/lib/utils';
import {
  APPLICATION_STATUS_LABELS,
  JOB_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;
  amount: number | string;
  status: QuotationStatus;
  message?: string | null;
  worker: { id: string; user: JobPerson };
}

interface CustomerJobDetail {
  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;
  workerMarkedCompleteAt?: string | null;
  category?: { id: string; name: string; slug?: string };
  worker?: { id: string; user: JobPerson } | null;
  images?: JobImage[];
  quotations?: JobQuotation[];
  reviews?: { overallRating: number; comment?: string | null }[];
}

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 quotationBadgeVariant(status: QuotationStatus) {
  switch (status) {
    case 'ACCEPTED':
      return 'success' as const;
    case 'REJECTED':
      return 'destructive' as const;
    case 'PENDING':
      return 'warning' as const;
    default:
      return 'secondary' 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>
  );
}

export default function CustomerJobDetailPage() {
  const { id } = useParams<{ id: string }>();
  const router = useRouter();
  const [job, setJob] = useState<CustomerJobDetail | null>(null);
  const [pageLoading, setPageLoading] = useState(true);
  const [hireModalOpen, setHireModalOpen] = useState(false);
  const [pendingHire, setPendingHire] = useState<JobQuotation | null>(null);
  const [acceptingId, setAcceptingId] = useState<string | null>(null);
  const [rejectingId, setRejectingId] = useState<string | null>(null);
  const [reviewEligibility, setReviewEligibility] = useState<{
    eligible: boolean;
    reason?: string;
    workerName?: string;
  } | null>(null);

  const loadReviewEligibility = () => {
    api<{ data: { eligible: boolean; reason?: string; workerName?: string } }>(
      `/reviews/eligible/${id}`
    )
      .then((res) => setReviewEligibility(res.data))
      .catch(() => setReviewEligibility(null));
  };

  const handleJobUpdated = async (updated: Record<string, unknown>) => {
    if (updated.status === 'OPEN' || updated.status === 'QUOTED') {
      try {
        const res = await api<{ data: CustomerJobDetail }>(`/jobs/${id}`);
        setJob(res.data);
        setReviewEligibility({ eligible: false, reason: 'Job reopened' });
      } catch (err) {
        console.error(err);
        setJob((prev) => (prev ? { ...prev, ...updated, worker: null } : prev));
      }
      return;
    }

    setJob((prev) => (prev ? { ...prev, ...updated } : prev));
    if (updated.status === 'COMPLETED') {
      loadReviewEligibility();
    }
  };

  useEffect(() => {
    if (!id) return;
    setPageLoading(true);
    Promise.all([
      api<{ data: CustomerJobDetail }>(`/jobs/${id}`),
      api<{ data: { eligible: boolean; reason?: string; workerName?: string } }>(
        `/reviews/eligible/${id}`
      ),
    ])
      .then(([jobRes, reviewRes]) => {
        setJob(jobRes.data);
        setReviewEligibility(reviewRes.data);
      })
      .catch(console.error)
      .finally(() => setPageLoading(false));
  }, [id]);

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

  const handleHireClick = (quotation: JobQuotation) => {
    setPendingHire(quotation);
    setHireModalOpen(true);
  };

  const handleConfirmHire = async () => {
    if (!pendingHire) return;
    setAcceptingId(pendingHire.id);
    try {
      await api(`/quotations/${pendingHire.id}/accept`, { method: 'PATCH' });
      setHireModalOpen(false);
      setPendingHire(null);
      await reloadJob();
    } catch (err) {
      console.error(err);
    } finally {
      setAcceptingId(null);
    }
  };

  const handleRejectApplication = async (applicationId: string) => {
    setRejectingId(applicationId);
    try {
      await api(`/quotations/${applicationId}/reject`, { method: 'PATCH' });
      await reloadJob();
    } catch (err) {
      console.error(err);
    } finally {
      setRejectingId(null);
    }
  };

  if (pageLoading || !job) {
    return (
      <DashboardLayout role="customer" title="Job details">
        <PortalShell width="wide">
          <PortalLoading label="Loading job…" />
        </PortalShell>
      </DashboardLayout>
    );
  }

  const applications = job.quotations ?? [];
  const canReceiveApplications = ['OPEN', 'QUOTED'].includes(job.status);
  const images = job.images ?? [];
  const existingReview = job.reviews?.[0] ?? null;
  const hiredWorker = job.worker;
  const isCompleted = job.status === 'COMPLETED';
  const isCancelled = job.status === 'CANCELLED';
  const isHired = ['ACCEPTED', 'IN_PROGRESS', 'COMPLETED'].includes(job.status);
  const showProgress = isHired && !isCancelled;
  const messagesHref = buildJobMessagesHref('customer', id);

  return (
    <DashboardLayout role="customer" title={job.title}>
      <PortalShell width="wide">
        <Link
          href="/customer/jobs"
          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 my jobs
        </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(job.status)} className="normal-case tracking-normal">
                {JOB_STATUS_LABELS[job.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={`${applications.length} received`}
                />
              )}
            </div>
          </CardContent>
        </Card>

        {showProgress ? (
          <div className="space-y-4">
            <JobStatusTimeline
              status={job.status}
              workerMarkedCompleteAt={job.workerMarkedCompleteAt}
            />
            <JobProgressPanel
              jobId={id}
              status={job.status}
              role="customer"
              workerMarkedCompleteAt={job.workerMarkedCompleteAt}
              onUpdated={handleJobUpdated}
            />
          </div>
        ) : isCancelled ? (
          <JobProgressPanel
            jobId={id}
            status={job.status}
            role="customer"
            onUpdated={handleJobUpdated}
          />
        ) : null}

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

            {images.length > 0 ? (
              <PortalSection icon={ImageIcon} title="Photos" description="Images attached to this job">
                <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>
              </PortalSection>
            ) : null}

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

            <JobCommentsSection jobId={id} />
          </div>

          <aside className="space-y-6 lg:sticky lg:top-20">
            {isHired && hiredWorker?.user ? (
              <PortalSection icon={UserRound} title="Hired worker" description="Working on this job">
                <div className="flex items-center gap-3">
                  <UserAvatar
                    firstName={hiredWorker.user.firstName}
                    lastName={hiredWorker.user.lastName}
                    avatarUrl={hiredWorker.user.avatarUrl}
                    size="sm"
                  />
                  <p className="font-semibold text-slate-900">
                    {hiredWorker.user.firstName} {hiredWorker.user.lastName}
                  </p>
                </div>
                <div className="mt-4 flex flex-col gap-2">
                  <Button
                    size="sm"
                    variant="outline"
                    className="w-full gap-1.5"
                    onClick={() => router.push(messagesHref)}
                  >
                    <MessageCircle className="h-4 w-4" />
                    Message worker
                  </Button>
                  {isCompleted && hiredWorker.id && job.category?.id ? (
                    <>
                      <Button
                        size="sm"
                        className="w-full gap-1.5"
                        onClick={() => router.push(buildCreateJobUrl(job.category!.id))}
                      >
                        <Send className="h-4 w-4" />
                        Hire again
                      </Button>
                      <SaveWorkerButton workerId={hiredWorker.id} />
                    </>
                  ) : null}
                </div>
              </PortalSection>
            ) : null}

            <PortalSection
              icon={MessageSquare}
              title={`Applications (${applications.length})`}
              description="Worker offers for this job"
            >
              {applications.length === 0 ? (
                <p className="text-sm text-muted">
                  {canReceiveApplications
                    ? 'Workers matching this category can apply. You will see their offers here.'
                    : 'No applications for this job.'}
                </p>
              ) : (
                <div className="space-y-3">
                  {applications.map((q) => {
                    const worker = q.worker.user;
                    const workerName = `${worker.firstName} ${worker.lastName}`;
                    return (
                      <Card key={q.id}>
                        <CardContent className="p-4">
                          <div className="flex items-start justify-between gap-3">
                            <div className="min-w-0">
                              <Link
                                href={`/workers/${q.worker.id}`}
                                className="font-semibold text-slate-900 hover:text-primary"
                              >
                                {workerName}
                              </Link>
                              <p className="mt-1 text-xl font-bold text-accent">
                                {formatCurrency(Number(q.amount))}
                              </p>
                              {q.message ? (
                                <p className="mt-2 text-sm text-muted line-clamp-3">{q.message}</p>
                              ) : null}
                            </div>
                            <Badge variant={quotationBadgeVariant(q.status)} className="shrink-0">
                              {APPLICATION_STATUS_LABELS[q.status]}
                            </Badge>
                          </div>
                          {q.status === 'PENDING' && canReceiveApplications ? (
                            <div className="mt-3 flex flex-wrap gap-2">
                              <Button
                                size="sm"
                                className="gap-1.5"
                                disabled={acceptingId === q.id || rejectingId === q.id}
                                onClick={() => handleHireClick(q)}
                              >
                                <CheckCircle2 className="h-3.5 w-3.5" />
                                Hire worker
                              </Button>
                              <Button
                                size="sm"
                                variant="outline"
                                disabled={acceptingId === q.id || rejectingId === q.id}
                                onClick={() => handleRejectApplication(q.id)}
                              >
                                {rejectingId === q.id ? (
                                  'Declining…'
                                ) : (
                                  <>
                                    <XCircle className="h-3.5 w-3.5" />
                                    Decline
                                  </>
                                )}
                              </Button>
                              <Button
                                size="sm"
                                variant="outline"
                                onClick={() =>
                                  router.push(
                                    buildJobMessagesHref('customer', id, { workerId: q.worker.id })
                                  )
                                }
                              >
                                Message
                              </Button>
                            </div>
                          ) : null}
                        </CardContent>
                      </Card>
                    );
                  })}
                </div>
              )}
            </PortalSection>

            {(existingReview || reviewEligibility?.eligible) && (
              <PortalSection icon={Star} title="Worker review" description="Share your experience">
                {existingReview ? (
                  <div className="space-y-2">
                    <StarRating rating={Number(existingReview.overallRating)} showValue />
                    {existingReview.comment ? (
                      <p className="border-l-2 border-slate-200 pl-3 text-sm text-slate-600">
                        {existingReview.comment}
                      </p>
                    ) : null}
                    <p className="text-xs text-muted">Thank you for your review.</p>
                  </div>
                ) : reviewEligibility?.eligible && reviewEligibility.workerName ? (
                  <ReviewForm
                    jobId={id}
                    workerName={reviewEligibility.workerName}
                    onSubmitted={() => {
                      api<{ data: CustomerJobDetail }>(`/jobs/${id}`).then((res) => {
                        setJob(res.data);
                        setReviewEligibility({ eligible: false, reason: 'Already reviewed' });
                      });
                    }}
                  />
                ) : null}
              </PortalSection>
            )}

            {isCompleted && !existingReview && reviewEligibility && !reviewEligibility.eligible ? (
              <Card>
                <CardContent className="p-4 text-sm text-muted">
                  {reviewEligibility.reason ||
                    'Reviews are only available for jobs where you hired a worker through an accepted quote.'}
                </CardContent>
              </Card>
            ) : null}

            {isCancelled ? (
              <Card className="border-amber-200 bg-amber-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-amber-100 text-amber-700">
                    <Briefcase className="h-6 w-6" />
                  </div>
                  <h2 className="font-bold text-amber-900">Job cancelled</h2>
                  <p className="mt-1 text-sm text-amber-800">
                    You can reopen it above if you still need help and want new quotes.
                  </p>
                </CardContent>
              </Card>
            ) : isCompleted ? (
              <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">This job has been marked as done.</p>
                </CardContent>
              </Card>
            ) : null}

            <Link href={messagesHref}>
              <Button variant="accent" className="w-full gap-2">
                <MessageCircle className="h-4 w-4" />
                Open messages
              </Button>
            </Link>
          </aside>
        </div>

        <HireDisclaimerModal
          open={hireModalOpen}
          onClose={() => {
            if (!acceptingId) {
              setHireModalOpen(false);
              setPendingHire(null);
            }
          }}
          onConfirm={handleConfirmHire}
          workerName={
            pendingHire
              ? `${pendingHire.worker.user.firstName} ${pendingHire.worker.user.lastName}`
              : undefined
          }
          intent="accept-quote"
          loading={acceptingId !== null}
        />
      </PortalShell>
    </DashboardLayout>
  );
}
