import {
  BeakerIcon,
  BellAlertIcon,
  BookOpenIcon,
  ChatBubbleLeftRightIcon,
  ClockIcon,
  PlusIcon,
  QuestionMarkCircleIcon,
  RectangleGroupIcon,
  RectangleStackIcon,
  ServerStackIcon,
  Squares2X2Icon,
} from "@heroicons/react/20/solid";
import { useLocation } from "react-use";
import { BranchEnvironmentIconSmall } from "~/assets/icons/EnvironmentIcons";
import { WaitpointTokenIcon } from "~/assets/icons/WaitpointTokenIcon";
import openBulkActionsPanel from "~/assets/images/open-bulk-actions-panel.png";
import selectRunsIndividually from "~/assets/images/select-runs-individually.png";
import selectRunsUsingFilters from "~/assets/images/select-runs-using-filters.png";
import { useEnvironment } from "~/hooks/useEnvironment";
import { useFeatures } from "~/hooks/useFeatures";
import { useOrganization } from "~/hooks/useOrganizations";
import { useProject } from "~/hooks/useProject";
import { type MinimumEnvironment } from "~/presenters/SelectBestEnvironmentPresenter.server";
import { NewBranchPanel } from "~/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.branches/route";
import {
  docsPath,
  v3BillingPath,
  v3CreateBulkActionPath,
  v3EnvironmentPath,
  v3EnvironmentVariablesPath,
  v3NewProjectAlertPath,
  v3NewSchedulePath,
} from "~/utils/pathBuilder";
import { AskAI } from "./AskAI";
import { InlineCode } from "./code/InlineCode";
import { environmentFullTitle, EnvironmentIcon } from "./environments/EnvironmentLabel";
import { Feedback } from "./Feedback";
import { EnvironmentSelector } from "./navigation/EnvironmentSelector";
import { Button, LinkButton } from "./primitives/Buttons";
import { Header1 } from "./primitives/Headers";
import { InfoPanel } from "./primitives/InfoPanel";
import { Paragraph } from "./primitives/Paragraph";
import { StepNumber } from "./primitives/StepNumber";
import { TextLink } from "./primitives/TextLink";
import { SimpleTooltip } from "./primitives/Tooltip";
import {
  InitCommandV3,
  PackageManagerProvider,
  TriggerDeployStep,
  TriggerDevStepV3,
} from "./SetupCommands";
import { StepContentContainer } from "./StepContentContainer";
import { V4Badge } from "./V4Badge";
import {
  ClientTabs,
  ClientTabsContent,
  ClientTabsList,
  ClientTabsTrigger,
} from "./primitives/ClientTabs";
import { GitHubSettingsPanel } from "~/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.github";

export function HasNoTasksDev() {
  return (
    <PackageManagerProvider>
      <div>
        <div className="mb-6 flex items-center justify-between border-b">
          <Header1 spacing>Get setup in 3 minutes</Header1>
          <div className="flex items-center gap-2">
            <Feedback
              button={
                <Button variant="minimal/small" LeadingIcon={ChatBubbleLeftRightIcon}>
                  I'm stuck!
                </Button>
              }
              defaultValue="help"
            />
          </div>
        </div>
        <StepNumber stepNumber="1" title="Run the CLI 'init' command in an existing project" />
        <StepContentContainer>
          <InitCommandV3 />
          <Paragraph spacing>
            You'll notice a new folder in your project called{" "}
            <InlineCode variant="small">trigger</InlineCode>. We've added a few simple example tasks
            in there to help you get started.
          </Paragraph>
        </StepContentContainer>
        <StepNumber stepNumber="2" title="Run the CLI 'dev' command" />
        <StepContentContainer>
          <TriggerDevStepV3 />
        </StepContentContainer>
        <StepNumber stepNumber="3" title="Waiting for tasks" displaySpinner />
        <StepContentContainer>
          <Paragraph>This page will automatically refresh.</Paragraph>
        </StepContentContainer>
      </div>
    </PackageManagerProvider>
  );
}

export function HasNoTasksDeployed({ environment }: { environment: MinimumEnvironment }) {
  return <DeploymentOnboardingSteps />;
}

export function SchedulesNoPossibleTaskPanel() {
  return (
    <InfoPanel
      title="Create your first scheduled task"
      icon={ClockIcon}
      iconClassName="text-schedules"
      panelClassName="max-w-full"
      accessory={
        <LinkButton
          to={docsPath("v3/tasks-scheduled")}
          variant="docs/small"
          LeadingIcon={BookOpenIcon}
        >
          How to schedule tasks
        </LinkButton>
      }
    >
      <Paragraph spacing variant="small">
        You have no scheduled tasks in your project. Before you can schedule a task you need to
        create a <InlineCode>schedules.task</InlineCode>.
      </Paragraph>
    </InfoPanel>
  );
}

export function SchedulesNoneAttached() {
  const organization = useOrganization();
  const project = useProject();
  const environment = useEnvironment();
  const location = useLocation();

  return (
    <InfoPanel
      title="Attach your first schedule"
      icon={ClockIcon}
      iconClassName="text-schedules"
      panelClassName="max-w-full"
    >
      <Paragraph spacing variant="small">
        Scheduled tasks will only run automatically if you connect a schedule to them, you can do
        this in the dashboard or using the SDK.
      </Paragraph>
      <div className="flex gap-2">
        <LinkButton
          to={`${v3NewSchedulePath(organization, project, environment)}${location.search}`}
          variant="secondary/medium"
          LeadingIcon={RectangleGroupIcon}
          className="inline-flex"
          leadingIconClassName="text-blue-500"
        >
          Use the dashboard
        </LinkButton>
        <LinkButton
          to={docsPath("v3/tasks-scheduled")}
          variant="docs/medium"
          LeadingIcon={BookOpenIcon}
          className="inline-flex"
        >
          Use the SDK
        </LinkButton>
      </div>
    </InfoPanel>
  );
}

export function BatchesNone() {
  return (
    <InfoPanel
      title="Triggering batches"
      icon={Squares2X2Icon}
      iconClassName="text-batches"
      panelClassName="max-w-full"
      accessory={
        <LinkButton to={docsPath("triggering")} variant="docs/small" LeadingIcon={BookOpenIcon}>
          How to trigger batches
        </LinkButton>
      }
    >
      <Paragraph spacing variant="small">
        You have no batches in this environment. You can trigger batches from your backend or from
        inside other tasks.
      </Paragraph>
    </InfoPanel>
  );
}

export function TestHasNoTasks() {
  const organization = useOrganization();
  const project = useProject();
  const environment = useEnvironment();
  return (
    <InfoPanel
      title="You don't have any tasks to test"
      icon={BeakerIcon}
      iconClassName="text-tests"
      panelClassName="max-w-full"
      accessory={
        <LinkButton
          to={v3EnvironmentPath(organization, project, environment)}
          variant="primary/small"
        >
          Create a task
        </LinkButton>
      }
    >
      <Paragraph spacing variant="small">
        Before testing a task, you must first create one. Follow the instructions on the{" "}
        <TextLink to={v3EnvironmentPath(organization, project, environment)}>Tasks page</TextLink>{" "}
        to create a task, then return here to test it.
      </Paragraph>
    </InfoPanel>
  );
}

export function DeploymentsNone() {
  return <DeploymentOnboardingSteps />;
}

export function DeploymentsNoneDev() {
  const organization = useOrganization();
  const project = useProject();
  const environment = useEnvironment();

  return (
    <>
      <div className="mb-6 flex items-center justify-between border-b">
        <div className="mb-2 flex items-center gap-2">
          <EnvironmentIcon environment={environment} className="-ml-1 size-8" />
          <Header1>Deploy your tasks</Header1>
        </div>
        <div className="flex items-center">
          <SimpleTooltip
            button={
              <LinkButton
                variant="small-menu-item"
                LeadingIcon={BookOpenIcon}
                leadingIconClassName="text-blue-500"
                to={docsPath("deployment/overview")}
              />
            }
            content="Deploy docs"
          />
          <SimpleTooltip
            button={
              <LinkButton
                variant="small-menu-item"
                LeadingIcon={QuestionMarkCircleIcon}
                leadingIconClassName="text-blue-500"
                to={docsPath("troubleshooting#deployment")}
              />
            }
            content="Troubleshooting docs"
          />
          <AskAI />
        </div>
      </div>
      <StepNumber stepNumber="→" title="Switch to a deployed environment" />
      <StepContentContainer className="mb-4 flex flex-col gap-4">
        <Paragraph>
          This is the Development environment. When you're ready to deploy your tasks, switch to a
          different environment.
        </Paragraph>
        <EnvironmentSelector
          organization={organization}
          project={project}
          environment={environment}
          className="w-fit border border-charcoal-600 bg-secondary hover:border-charcoal-550 hover:bg-charcoal-600"
        />
      </StepContentContainer>
    </>
  );
}

export function AlertsNoneDev() {
  return (
    <div className="space-y-8">
      <InfoPanel
        icon={BellAlertIcon}
        iconClassName="text-alerts"
        title="Adding alerts"
        panelClassName="max-w-full"
      >
        <Paragraph spacing variant="small">
          You can get alerted when deployed runs fail.
        </Paragraph>
        <Paragraph spacing variant="small">
          We don't support alerts in the Development environment. Switch to a deployed environment
          to setup alerts.
        </Paragraph>
        <div className="flex gap-3">
          <LinkButton
            to={docsPath("troubleshooting-alerts")}
            variant="docs/medium"
            LeadingIcon={BookOpenIcon}
            className="inline-flex"
          >
            How to setup alerts
          </LinkButton>
        </div>
      </InfoPanel>
      <SwitcherPanel />
    </div>
  );
}

export function AlertsNoneDeployed() {
  const organization = useOrganization();
  const project = useProject();
  const environment = useEnvironment();

  return (
    <div className="space-y-8">
      <InfoPanel
        icon={BellAlertIcon}
        iconClassName="text-alerts"
        title="Adding alerts"
        panelClassName="max-w-full"
      >
        <Paragraph spacing variant="small">
          You can get alerted when deployed runs fail. We currently support sending Slack, Email,
          and webhooks.
        </Paragraph>

        <div className="flex items-center justify-between gap-3">
          <LinkButton
            to={docsPath("troubleshooting-alerts")}
            variant="docs/medium"
            LeadingIcon={BookOpenIcon}
            className="inline-flex"
          >
            Alerts docs
          </LinkButton>
          <LinkButton
            to={v3NewProjectAlertPath(organization, project, environment)}
            variant="primary/medium"
            LeadingIcon={PlusIcon}
            shortcut={{ key: "n" }}
          >
            New alert
          </LinkButton>
        </div>
      </InfoPanel>
    </div>
  );
}

export function QueuesHasNoTasks() {
  const organization = useOrganization();
  const project = useProject();
  const environment = useEnvironment();

  return (
    <InfoPanel
      title="You don't have any queues"
      icon={RectangleStackIcon}
      iconClassName="text-queues"
      panelClassName="max-w-md"
      accessory={
        <LinkButton
          to={v3EnvironmentPath(organization, project, environment)}
          variant="primary/small"
        >
          Create a task
        </LinkButton>
      }
    >
      <Paragraph spacing variant="small">
        Queues will appear here when you have created a task in this environment. Follow the
        instructions on the{" "}
        <TextLink to={v3EnvironmentPath(organization, project, environment)}>Tasks page</TextLink>{" "}
        to create a task, then return here to see its queue.
      </Paragraph>
    </InfoPanel>
  );
}

export function NoWaitpointTokens() {
  return (
    <InfoPanel
      title="You don't have any waitpoint tokens"
      icon={WaitpointTokenIcon}
      iconClassName="text-sky-500"
      panelClassName="max-w-md"
      accessory={
        <LinkButton to={docsPath("wait-for-token")} variant="docs/small" LeadingIcon={BookOpenIcon}>
          Waitpoint docs
        </LinkButton>
      }
    >
      <Paragraph spacing variant="small">
        Waitpoint tokens pause task runs until you complete the token. They're commonly used for
        approval workflows and other scenarios where you need to wait for external confirmation,
        such as human-in-the-loop processes.
      </Paragraph>
    </InfoPanel>
  );
}

export function BranchesNoBranchableEnvironment() {
  const { isManagedCloud } = useFeatures();
  const organization = useOrganization();

  if (!isManagedCloud) {
    return (
      <InfoPanel
        title="Create a preview environment"
        icon={BranchEnvironmentIconSmall}
        iconClassName="text-preview"
        panelClassName="max-w-full"
      >
        <Paragraph spacing variant="small">
          To add branches you need to have a <InlineCode>RuntimeEnvironment</InlineCode> where{" "}
          <InlineCode>isBranchableEnvironment</InlineCode> is true. We recommend creating a
          dedicated one using the "PREVIEW" type.
        </Paragraph>
      </InfoPanel>
    );
  }

  return (
    <InfoPanel
      title="Upgrade to get preview branches"
      icon={BranchEnvironmentIconSmall}
      iconClassName="text-preview"
      panelClassName="max-w-full"
      accessory={
        <LinkButton variant="primary/small" to={v3BillingPath(organization)}>
          Upgrade
        </LinkButton>
      }
    >
      <Paragraph spacing variant="small">
        Preview branches in Trigger.dev create isolated environments for testing new features before
        production.
      </Paragraph>
      <Paragraph variant="small">
        You must be on <V4Badge inline /> to access preview branches. Read our{" "}
        <TextLink to={docsPath("upgrade-to-v4")}>upgrade to v4 guide</TextLink> to learn more.
      </Paragraph>
    </InfoPanel>
  );
}

export function BranchesNoBranches({
  parentEnvironment,
  limits,
  canUpgrade,
}: {
  parentEnvironment: { id: string };
  limits: { used: number; limit: number };
  canUpgrade: boolean;
}) {
  const organization = useOrganization();

  if (limits.used >= limits.limit) {
    return (
      <InfoPanel
        title="Upgrade to get preview branches"
        icon={BranchEnvironmentIconSmall}
        iconClassName="text-preview"
        panelClassName="max-w-full"
        accessory={
          canUpgrade ? (
            <LinkButton variant="primary/small" to={v3BillingPath(organization)}>
              Upgrade
            </LinkButton>
          ) : (
            <Feedback
              button={<Button variant="primary/small">Request more</Button>}
              defaultValue="help"
            />
          )
        }
      >
        <Paragraph spacing variant="small">
          You've reached the limit ({limits.used}/{limits.limit}) of branches for your plan. Upgrade
          to get branches.
        </Paragraph>
      </InfoPanel>
    );
  }

  return (
    <InfoPanel
      title="Create your first branch"
      icon={BranchEnvironmentIconSmall}
      iconClassName="text-preview"
      panelClassName="max-w-full"
      accessory={
        <NewBranchPanel
          button={
            <Button
              variant="primary/small"
              LeadingIcon={PlusIcon}
              leadingIconClassName="text-white"
            >
              New branch
            </Button>
          }
          parentEnvironment={parentEnvironment}
        />
      }
    >
      <Paragraph spacing variant="small">
        Branches are a way to test new features in isolation before merging them into the main
        environment.
      </Paragraph>
      <Paragraph spacing variant="small">
        Branches are only available when using <V4Badge inline /> or above. Read our{" "}
        <TextLink to={docsPath("upgrade-to-v4")}>v4 upgrade guide</TextLink> to learn more.
      </Paragraph>
    </InfoPanel>
  );
}

export function SwitcherPanel({ title = "Switch to a deployed environment" }: { title?: string }) {
  const organization = useOrganization();
  const project = useProject();
  const environment = useEnvironment();

  return (
    <div className="flex items-center rounded-md border border-grid-bright bg-background-bright p-3">
      <Paragraph variant="small" className="grow">
        {title}
      </Paragraph>
      <EnvironmentSelector
        organization={organization}
        project={project}
        environment={environment}
        className="w-auto grow-0 rounded-sm bg-grid-bright"
      />
    </div>
  );
}

export function BulkActionsNone() {
  const organization = useOrganization();
  const project = useProject();
  const environment = useEnvironment();

  return (
    <div>
      <div className="mb-6 flex items-center justify-between border-b pb-0.5">
        <Header1 spacing>Create a bulk action</Header1>
        <div className="flex items-center gap-2">
          <LinkButton
            variant="primary/small"
            LeadingIcon={PlusIcon}
            to={v3CreateBulkActionPath(organization, project, environment)}
          >
            New bulk action
          </LinkButton>
        </div>
      </div>
      <StepNumber stepNumber="1" title="Select runs individually" />
      <StepContentContainer className="mb-4 flex flex-col gap-4">
        <Paragraph>Select runs from the runs page individually.</Paragraph>
        <div>
          <img src={selectRunsIndividually} alt="Select runs individually" />
        </div>
      </StepContentContainer>
      <div className="mb-5 ml-9 flex items-center gap-2">
        <div className="h-px w-full bg-grid-bright" />
        <Paragraph variant="extra-small" className="text-text-dimmed">
          OR
        </Paragraph>
        <div className="h-px w-full bg-grid-bright" />
      </div>
      <StepNumber stepNumber="2" title="Select runs using filters" />
      <StepContentContainer className="flex flex-col gap-4">
        <Paragraph>
          Use the filter menu on the runs page to select just the runs you want to bulk action.
        </Paragraph>
        <div>
          <img src={selectRunsUsingFilters} alt="Select runs using filters" />
        </div>
      </StepContentContainer>
      <StepNumber stepNumber="3" title="Open the bulk action panel" />
      <StepContentContainer className="flex flex-col gap-4">
        <Paragraph>Click the “Bulk actions” button in the top right of the runs page.</Paragraph>
        <div>
          <img src={openBulkActionsPanel} alt="Open the bulk action panel" />
        </div>
      </StepContentContainer>
    </div>
  );
}

function DeploymentOnboardingSteps() {
  const environment = useEnvironment();
  const organization = useOrganization();
  const project = useProject();

  return (
    <PackageManagerProvider>
      <div className="mb-2 flex items-center justify-between border-b">
        <div className="mb-2 flex min-w-0 items-center gap-2">
          <EnvironmentIcon environment={environment} className="-ml-1 size-8 shrink-0" />
          <Header1 className="truncate">Deploy your tasks to {environmentFullTitle(environment)}</Header1>
        </div>
        <div className="flex items-center">
          <SimpleTooltip
            button={
              <LinkButton
                variant="small-menu-item"
                LeadingIcon={BookOpenIcon}
                leadingIconClassName="text-blue-500"
                to={docsPath("deployment/overview")}
              />
            }
            content="Deploy docs"
          />
          <SimpleTooltip
            button={
              <LinkButton
                variant="small-menu-item"
                LeadingIcon={QuestionMarkCircleIcon}
                leadingIconClassName="text-blue-500"
                to={docsPath("troubleshooting#deployment")}
              />
            }
            content="Troubleshooting docs"
          />
          <AskAI />
        </div>
      </div>
      <ClientTabs defaultValue="github">
        <ClientTabsList variant="segmented" className="mb-6">
          <ClientTabsTrigger value={"github"} variant="segmented" layoutId="deploy-tabs">
            GitHub
          </ClientTabsTrigger>
          <ClientTabsTrigger value={"cli"} variant="segmented" layoutId="deploy-tabs">
            Manual
          </ClientTabsTrigger>
          <ClientTabsTrigger value={"github-actions"} variant="segmented" layoutId="deploy-tabs">
            GitHub Actions
          </ClientTabsTrigger>
        </ClientTabsList>
        <ClientTabsContent value={"github"}>
          <StepNumber stepNumber="1" title="Connect your GitHub repository" />
          <StepContentContainer>
            <Paragraph spacing>
              Deploy automatically with every push. Read the{" "}
              <TextLink to={docsPath("github-integration")}>full guide</TextLink>.
            </Paragraph>
            <div className="w-fit">
              <GitHubSettingsPanel
                organizationSlug={organization.slug}
                projectSlug={project.slug}
                environmentSlug={environment.slug}
                billingPath={v3BillingPath({ slug: organization.slug })}              
              />
            </div>
          </StepContentContainer>
        </ClientTabsContent>
        <ClientTabsContent value={"cli"}>
          <StepNumber stepNumber="1" title="Run the CLI 'deploy' command" />
          <StepContentContainer>
            <Paragraph spacing>
              This will deploy your tasks to the {environmentFullTitle(environment)} environment.
              Read the <TextLink to={docsPath("deployment/overview")}>full guide</TextLink>.
            </Paragraph>
            <TriggerDeployStep environment={environment} />
          </StepContentContainer>
        </ClientTabsContent>
        <ClientTabsContent value={"github-actions"}>
          <StepNumber stepNumber="1" title="Deploy using GitHub Actions" />
          <StepContentContainer>
            <Paragraph spacing>
              Read the <TextLink to={docsPath("github-actions")}>GitHub Actions guide</TextLink> to
              get started.
            </Paragraph>
          </StepContentContainer>
        </ClientTabsContent>
      </ClientTabs>

      <StepNumber stepNumber="2" title="Waiting for tasks to deploy" displaySpinner />
      <StepContentContainer>
        <Paragraph>This page will automatically refresh when your tasks are deployed.</Paragraph>
      </StepContentContainer>
    </PackageManagerProvider>
  );
}
