import { Head, Link } from '@inertiajs/react';
import {
    AlertTriangle,
    ArrowRight,
    CalendarClock,
    CheckCircle2,
    ClipboardCheck,
    DollarSign,
    History,
    Layers,
    PlugZap,
    Plus,
    ShieldAlert,
    Sun,
    Workflow,
} from 'lucide-react';
import { ActivityTimeline } from '@/components/crm/timeline';
import { JobList } from '@/components/crm/job-list';
import { KpiTile } from '@/components/crm/kpi-tile';
import { PipelineBoard } from '@/components/crm/pipeline-board';
import {
    Callout,
    EmptyState,
    PageHeader,
    SectionCard,
} from '@/components/crm/page-header';
import { RuleFlag } from '@/components/crm/status-badge';
import { Button } from '@/components/ui/button';
import { usePermissions } from '@/hooks/use-permissions';
import { useRelease } from '@/hooks/use-release';
import {
    formatCompactCurrency,
    formatDuration,
    formatLongDate,
    formatNumber,
} from '@/lib/format';
import { cn } from '@/lib/utils';
import { dashboard } from '@/routes';
import {
    create as jobsCreate,
    index as jobsIndex,
    show as jobShow,
} from '@/routes/jobs';
import type { AttentionItem, DashboardProps } from '@/types';

export default function Dashboard({
    metrics,
    pipeline,
    byState,
    attention,
    trends,
    deltas,
    upcomingInstallations,
    awaitingInspection,
    awaitingGridCloseout,
    myJobs,
    recentActivity,
    stalledThresholdDays,
    can,
}: DashboardProps) {
    const { can: canDo } = usePermissions();
    // The dashboard is built from jobs, which are a released part like any
    // other. When they are off, the page says so rather than counting records
    // it is not showing anywhere else.
    const { enabled } = useRelease();
    const jobsReleased = enabled('jobs');

    const activePipeline = pipeline.filter(
        (stage) => stage.value !== 'completed' && stage.value !== 'cancelled',
    );

    const jobsUrl = (params: Record<string, string>) =>
        jobsIndex({ query: params }).url;

    return (
        <>
            <Head title="Dashboard" />

            <PageHeader
                eyebrow={
                    jobsReleased ? (
                        <>
                            <Sun className="size-3.5 text-solar" />
                            <span>
                                {formatLongDate(new Date().toISOString())}
                            </span>
                            <span
                                aria-hidden
                                className="text-muted-foreground/50"
                            >
                                ·
                            </span>
                            <span>
                                {formatNumber(metrics.activeJobs)} active jobs
                                across {byState.length} states
                            </span>
                        </>
                    ) : (
                        <>
                            <Layers className="size-3.5 text-solar" />
                            <span>Dashboard</span>
                        </>
                    )
                }
                title="Operations dashboard"
                description="Where every installation stands, what it is waiting on, and what needs a person today."
                actions={
                    jobsReleased ? (
                        <>
                            <Button variant="outline" size="sm" asChild>
                                <Link href={jobsIndex()}>
                                    All jobs
                                    <ArrowRight className="size-4" />
                                </Link>
                            </Button>
                            {canDo('jobs.create') ? (
                                <Button size="sm" asChild>
                                    <Link href={jobsCreate()}>
                                        <Plus className="size-4" />
                                        New job
                                    </Link>
                                </Button>
                            ) : null}
                        </>
                    ) : null
                }
            />

            {jobsReleased ? (
                <>
            {/* The tiles are grouped by shape rather than poured into one
                long row. The two figures that carry an eight week trend sit
                together, and the three that carry only a number sit together,
                so the cards in a row come out the same height because their
                contents match — rather than a short tile stretching into a
                mostly empty box to keep up with a tall neighbour. */}
            <div className="grid gap-3 sm:grid-cols-2">
                <KpiTile
                    label="Active jobs"
                    value={formatNumber(metrics.activeJobs)}
                    hint={`${formatNumber(metrics.newLeads)} still in sales`}
                    icon={Workflow}
                    tone="solar"
                    href={jobsUrl({ scope: 'active' })}
                    series={trends.created}
                    seriesType="bars"
                    delta={{
                        value: deltas.newJobs,
                        label: 'New jobs this week versus the week before',
                    }}
                    footer="New jobs per week, last 8 weeks"
                />

                <KpiTile
                    label="Completed this month"
                    value={formatNumber(metrics.completedThisMonth)}
                    hint="Fully closed out"
                    icon={CheckCircle2}
                    tone="success"
                    series={trends.completed}
                    delta={{
                        value: deltas.completed,
                        label: 'Completed in the last 30 days versus the 30 before',
                    }}
                    footer="Installs completed per week, last 8 weeks"
                />
            </div>

            {/* Three columns only when there are three tiles to fill them: on a
                role without the financials permission the pipeline value tile
                is dropped, and a third column would otherwise be left empty. */}
            <div
                className={cn(
                    'grid gap-3 sm:grid-cols-2',
                    can.viewFinancials && 'xl:grid-cols-3',
                )}
            >
                {can.viewFinancials ? (
                    <KpiTile
                        label="Pipeline value"
                        value={formatCompactCurrency(metrics.pipelineValue)}
                        hint="Contract value of active jobs"
                        icon={DollarSign}
                        tone="info"
                    />
                ) : null}

                <KpiTile
                    label="Awaiting inspection"
                    value={formatNumber(metrics.awaitingInspection)}
                    hint={
                        byState.some((row) => row.requiresIndependentInspection)
                            ? 'Includes Victorian independent inspections'
                            : 'Electrical inspection stage'
                    }
                    icon={ClipboardCheck}
                    tone={metrics.awaitingInspection > 0 ? 'warning' : 'slate'}
                    href={jobsUrl({ status: 'inspection_pending' })}
                />

                <KpiTile
                    label="Awaiting grid closeout"
                    value={formatNumber(metrics.awaitingGridCloseout)}
                    hint="Network approval, metering and export"
                    icon={PlugZap}
                    tone={metrics.awaitingGridCloseout > 0 ? 'info' : 'slate'}
                    href={jobsUrl({ status: 'grid_connection' })}
                />
            </div>

            <SectionCard
                title="Needs attention now"
                description="Hard stops first, then work that has stopped moving. These are the jobs that cost money when they slip."
                icon={ShieldAlert}
                tone={attention.some((job) => job.reason_type === 'blocked') ? 'danger' : 'warning'}
                actions={
                    <Button variant="ghost" size="sm" asChild>
                        <Link href={jobsUrl({ scope: 'stalled' })}>
                            Chasing list
                            <ArrowRight className="size-4" />
                        </Link>
                    </Button>
                }
            >
                {attention.length === 0 ? (
                    <EmptyState
                        icon={CheckCircle2}
                        title="Everything is moving"
                        description={`No blocked jobs and nothing sitting still for more than ${stalledThresholdDays} days.`}
                    />
                ) : (
                    <ul className="divide-hairline divide-y">
                        {attention.map((job) => (
                            <AttentionRow
                                key={job.id}
                                job={job}
                                href={jobShow(job.id).url}
                            />
                        ))}
                    </ul>
                )}
            </SectionCard>

            <SectionCard
                title="Installation pipeline"
                description="Every stage of the Australian solar process. Select a stage to open that slice of the jobs list."
                icon={Workflow}
                tone="solar"
            >
                <PipelineBoard
                    stages={activePipeline}
                    hrefFor={(stage) => jobsUrl({ status: stage.value })}
                />
            </SectionCard>

            {/* A band of two panels, each holding a list that grows as the
                business does. They are given one height and the lists scroll
                inside them, so a quiet week in the install diary never leaves
                a tall empty column beside a long inspection queue. */}
            <div className="grid gap-4 xl:grid-cols-2">
                <SectionCard
                    title="Upcoming installations"
                    description="Booked install dates, soonest first."
                    icon={CalendarClock}
                    tone="amber"
                    className="flex flex-col xl:h-[30rem]"
                    bodyClassName="min-h-0 flex-1 overflow-y-auto"
                    actions={
                        <Button variant="ghost" size="sm" asChild>
                            <Link href={jobsIndex()}>View all</Link>
                        </Button>
                    }
                >
                    {upcomingInstallations.length === 0 ? (
                        <EmptyState
                            title="No install dates booked"
                            description="Jobs appear here once an installation date is scheduled."
                        />
                    ) : (
                        <JobList
                            jobs={upcomingInstallations}
                            showInstallDate
                            jobHref={(id) => jobShow(id).url}
                        />
                    )}
                </SectionCard>

                <SectionCard
                    title="Awaiting electrical inspection"
                    description="Nothing here can be energised until the inspection is passed."
                    icon={ClipboardCheck}
                    tone="warning"
                    className="flex flex-col xl:h-[30rem]"
                    bodyClassName="min-h-0 flex-1 overflow-y-auto"
                    actions={
                        <Button variant="ghost" size="sm" asChild>
                            <Link href={jobsUrl({ status: 'inspection_pending' })}>
                                View all
                            </Link>
                        </Button>
                    }
                >
                    {byState.some((row) => row.requiresIndependentInspection) ? (
                        <Callout
                            tone="info"
                            className="mb-3"
                            title="Victoria requires an independent inspection"
                        >
                            Solar PV is prescribed electrical work there, so a
                            Licensed Electrical Inspector must pass the system
                            and issue a Certificate of Electrical Safety before
                            it can be energised.
                        </Callout>
                    ) : null}

                    {awaitingInspection.length === 0 ? (
                        <EmptyState
                            title="Nothing awaiting inspection"
                            description="Installed jobs waiting on an inspector will appear here."
                        />
                    ) : (
                        <JobList
                            jobs={awaitingInspection}
                            showWaitingOn
                            jobHref={(id) => jobShow(id).url}
                        />
                    )}
                </SectionCard>
            </div>

            <div className="grid gap-4 xl:grid-cols-[1.15fr_1fr]">
                <SectionCard
                    title="Compliance by state"
                    description="Grid rules, inspection requirements and rebate programs follow the installation address."
                    icon={ShieldAlert}
                    tone="info"
                    className="flex flex-col xl:h-[28rem]"
                    bodyClassName="min-h-0 flex-1 overflow-y-auto"
                >
                    {byState.length === 0 ? (
                        <EmptyState
                            title="No active jobs by state yet"
                            description="Create a job with an installation site to see the state breakdown."
                        />
                    ) : (
                        <ul className="space-y-2.5">
                            {byState.map((row) => {
                                const maxJobs = Math.max(
                                    ...byState.map((candidate) => candidate.jobsCount),
                                    1,
                                );

                                return (
                                    <li key={row.state}>
                                        <div className="flex items-center justify-between gap-3">
                                            <div className="flex min-w-0 items-center gap-2">
                                                <span className="text-sm font-medium">
                                                    {row.label}
                                                </span>
                                                {row.awaitingInspectionCount >
                                                0 ? (
                                                    <span className="crm-num text-warning text-xs font-medium">
                                                        {
                                                            row.awaitingInspectionCount
                                                        }{' '}
                                                        awaiting
                                                    </span>
                                                ) : null}
                                            </div>
                                            <span className="crm-num text-muted-foreground text-xs">
                                                {formatNumber(row.jobsCount)} jobs
                                            </span>
                                        </div>
                                        <div className="bg-muted mt-1.5 h-1.5 overflow-hidden rounded-full">
                                            <div
                                                className="bg-solar/70 h-full rounded-full"
                                                style={{
                                                    width: `${Math.round(
                                                        (row.jobsCount / maxJobs) * 100,
                                                    )}%`,
                                                }}
                                            />
                                        </div>
                                        <div className="mt-1.5 flex flex-wrap gap-1">
                                            {row.requiresIndependentInspection ? (
                                                <RuleFlag tone="info">
                                                    Independent inspection
                                                </RuleFlag>
                                            ) : null}
                                            {row.requiresNoticeOfCompletion ? (
                                                <RuleFlag tone="warning">
                                                    Notice of Completion for STCs
                                                </RuleFlag>
                                            ) : null}
                                            {row.rebateProgram ? (
                                                <RuleFlag tone="solar">
                                                    {row.rebateProgram}
                                                </RuleFlag>
                                            ) : null}
                                            {!row.requiresIndependentInspection &&
                                            !row.requiresNoticeOfCompletion &&
                                            !row.rebateProgram ? (
                                                <span className="text-muted-foreground text-[11px]">
                                                    Standard grid pre-approval and
                                                    electrical certificate
                                                </span>
                                            ) : null}
                                        </div>
                                    </li>
                                );
                            })}
                        </ul>
                    )}
                </SectionCard>

                <SectionCard
                    title="Recent activity"
                    description="The latest entries across every job timeline."
                    icon={History}
                    className="flex flex-col xl:max-h-[28rem]"
                    bodyClassName="min-h-0 flex-1 overflow-y-auto"
                >
                    <ActivityTimeline
                        entries={recentActivity}
                        jobHref={(id) => jobShow(id).url}
                    />
                </SectionCard>
            </div>

            <div className="grid gap-4 xl:grid-cols-2">
                <SectionCard
                    title="Awaiting grid closeout"
                    description="Network completion evidence, meter change and export approval."
                    icon={PlugZap}
                    tone="info"
                    className="flex flex-col xl:h-[24rem]"
                    bodyClassName="min-h-0 flex-1 overflow-y-auto"
                >
                    {awaitingGridCloseout.length === 0 ? (
                        <EmptyState
                            title="No jobs in closeout"
                            description="Installed jobs in the connection stage appear here."
                        />
                    ) : (
                        <JobList
                            jobs={awaitingGridCloseout}
                            showWaitingOn
                            jobHref={(id) => jobShow(id).url}
                        />
                    )}
                </SectionCard>

                {myJobs.length > 0 ? (
                    <SectionCard
                        title="My jobs"
                        description="Jobs you own, sell, run or install."
                        icon={Workflow}
                        tone="solar"
                        className="flex flex-col xl:h-[24rem]"
                        bodyClassName="min-h-0 flex-1 overflow-y-auto"
                    >
                        <JobList
                            jobs={myJobs}
                            showWaitingOn
                            jobHref={(id) => jobShow(id).url}
                        />
                    </SectionCard>
                ) : null}
            </div>
                </>
            ) : (
                <SectionCard
                    title="The job pipeline is not switched on yet"
                    description="This installation is being released in parts, and jobs have not been handed over."
                    icon={Layers}
                >
                    <p className="text-sm leading-relaxed text-muted-foreground">
                        When jobs are switched on, this dashboard fills in with
                        the pipeline, the install diary and the work that needs
                        a person today. Nothing has been lost in the meantime:
                        the records are waiting behind the release switch in
                        Settings, and switching it on puts them back exactly as
                        they were.
                    </p>
                </SectionCard>
            )}
        </>
    );
}

function AttentionRow({
    job,
    href,
}: {
    job: AttentionItem;
    href: string;
}) {
    return (
        <li>
            <Link
                href={href}
                className="hover:bg-accent/40 -mx-1 flex flex-col gap-2 rounded-lg px-2 py-3 transition-colors lg:flex-row lg:items-center lg:gap-4"
            >
                <div className="flex min-w-0 flex-1 items-start gap-3">
                    <span
                        aria-hidden
                        className={cn(
                            'mt-1 flex size-6 shrink-0 items-center justify-center rounded-md',
                            job.reason_type === 'blocked'
                                ? 'bg-danger-soft text-danger'
                                : job.reason_type === 'warning'
                                  ? 'bg-warning-soft text-warning'
                                  : 'bg-info-soft text-info',
                        )}
                    >
                        {job.reason_type === 'blocked' ? (
                            <ShieldAlert className="size-3.5" />
                        ) : (
                            <AlertTriangle className="size-3.5" />
                        )}
                    </span>
                    <div className="min-w-0">
                        <div className="flex flex-wrap items-center gap-x-2">
                            <span className="font-mono text-xs font-medium">
                                {job.job_number}
                            </span>
                            <span className="truncate text-sm font-medium">
                                {job.customer?.name ?? 'No customer'}
                            </span>
                            <span className="text-muted-foreground truncate text-xs">
                                {job.status.label}
                            </span>
                        </div>
                        <p className="text-muted-foreground mt-0.5 text-xs">
                            {job.reason}
                        </p>
                        {job.site ? (
                            <p className="text-muted-foreground/80 mt-0.5 truncate text-[11px]">
                                {job.site.address}
                                {job.site.distribution_network
                                    ? ` · ${job.site.distribution_network}`
                                    : ''}
                            </p>
                        ) : null}
                    </div>
                </div>

                <div className="flex items-center gap-4 lg:w-64 lg:shrink-0 lg:justify-end">
                    <span className="text-muted-foreground min-w-0 truncate text-xs">
                        {job.status.waiting_on}
                    </span>
                    <span className="crm-num w-16 shrink-0 text-right text-xs font-medium">
                        {formatDuration(job.days_in_status)}
                    </span>
                </div>
            </Link>
        </li>
    );
}

Dashboard.layout = {
    breadcrumbs: [
        {
            title: 'Dashboard',
            href: dashboard(),
        },
    ],
};
