"use client";

import { useState } from "react";
import { useMutation } from "@tanstack/react-query";
import { PortfolioSettingsType } from "../../../utils";
import { Button } from "@/app/shadcn_components/ui/button";
import { Input } from "@/app/shadcn_components/ui/input";
import { useRouter } from "next/navigation";
import { handleNumericKeyDown } from "@/app/utils";
import {
  Select,
  SelectContent,
  SelectGroup,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/app/shadcn_components/ui/select";
import { PortfolioStatus as PortfolioStatusOptions } from "@/app/db/schema/portfolio";
import { PortfolioGoal as PortfolioGoalOptions } from "@/app/db/schema/portfolio";
import { useSession } from "next-auth/react";

function SettingsDropdown({
  startingValue,
  options,
  setOption,
}: {
  startingValue: string;
  options: string[];
  setOption: (option: string) => void;
}) {
  return (
    <Select onValueChange={(newValue) => setOption(newValue)}>
      <SelectTrigger className="w-56">
        <SelectValue placeholder={startingValue} />
      </SelectTrigger>
      <SelectContent>
        <SelectGroup>
          {options.map((option, idx) => (
            <SelectItem value={option} key={idx}>
              {option}
            </SelectItem>
          ))}
        </SelectGroup>
      </SelectContent>
    </Select>
  );
}

type updateSettingsArgs = {
  userId: bigint;
  portfolioId: string;
  name: string | null;
  budget: number | string | undefined | null;
  goal: (typeof PortfolioGoalOptions)[number] | null;
  status: (typeof PortfolioStatusOptions)[number] | null;
};

type bodyType = {
  name?: string;
  budget?: number | string;
  goal?: string;
  status?: string;
};

const updateSettings = async ({
  userId,
  portfolioId,
  name,
  budget,
  goal,
  status,
}: updateSettingsArgs) => {
  const permissionsReponse = await fetch(
    `/api/portfolio/${portfolioId}/permissions`,
    {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ userId: userId.toString(), action: "update" }),
    },
  );

  const permissionsData = await permissionsReponse.json();
  if (!permissionsData.permitted) {
    throw new Error("User is not permitted to update this portfolio");
  }

  const body: bodyType = {};
  if (name) body.name = name;
  if (budget) body.budget = budget;
  if (goal) body.goal = goal;
  if (status) body.status = status;

  const response = await fetch(`/api/portfolio/${portfolioId}`, {
    method: "PUT",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(body),
  });

  if (!response.ok) throw new Error("Network response was not ok");
  return response.json();
};

function SettingRow({
  label,
  description,
  children,
}: {
  label: string;
  description: string;
  children: React.ReactNode;
}) {
  return (
    <div className="py-4 border-b border-gray-100 last:border-0">
      <div className="flex items-start justify-between gap-6">
        <div className="min-w-0 flex-1">
          <p className="text-sm font-medium text-gray-900">{label}</p>
          <p className="text-sm text-gray-500 mt-0.5">{description}</p>
        </div>
        <div className="flex items-center gap-2 shrink-0">{children}</div>
      </div>
    </div>
  );
}

export default function GeneralSettingsForm({
  portfolioId,
  portfolioSettingsData,
}: {
  portfolioId: string;
  portfolioSettingsData: PortfolioSettingsType;
}) {
  const session = useSession();
  const router = useRouter();

  const { mutate } = useMutation(updateSettings, {
    onSuccess: () => router.refresh(),
    onError: (error) => console.log(error),
  });

  const [portfolioName, setPortfolioName] = useState(portfolioSettingsData.name);
  const [portfolioBudget, setPortfolioBudget] = useState<number | string | null>(
    portfolioSettingsData.budget,
  );
  const [portfolioGoal, setPortfolioGoal] = useState(portfolioSettingsData.goal);
  const [portfolioStatus, setPortfolioStatus] = useState(portfolioSettingsData.status);

  if (session.status === "loading") return <div>Loading...</div>;
  if (!session.data) return null;

  const userId = session.data.user.dbId;

  return (
    <div>
      <h2 className="text-base font-semibold text-gray-900 mb-1">General</h2>
      <p className="text-sm text-gray-500 mb-4">Manage your portfolio settings.</p>

      <div className="border border-gray-200 rounded-lg bg-white px-4">
        <SettingRow
          label="Portfolio Name"
          description="Permanently change the name of your portfolio."
        >
          <Input
            value={portfolioName}
            onChange={(e) => setPortfolioName(e.target.value)}
            className="w-48"
          />
          <Button
            size="sm"
            onClick={() =>
              mutate({ userId, portfolioId, name: portfolioName, budget: null, goal: null, status: null })
            }
          >
            Save
          </Button>
        </SettingRow>

        <SettingRow
          label="Budget"
          description="The total budget across all properties. Works aim to stay within this budget."
        >
          <Input
            type="number"
            value={portfolioBudget ?? undefined}
            onChange={(e) => setPortfolioBudget(Number(e.target.value))}
            onKeyDown={(e) => handleNumericKeyDown(e)}
            className="w-48"
          />
          <Button
            size="sm"
            onClick={() =>
              mutate({ userId, portfolioId, name: null, budget: portfolioBudget, goal: null, status: null })
            }
          >
            Save
          </Button>
        </SettingRow>

        <SettingRow
          label="Goal"
          description="The overall aim of the works conducted on this portfolio."
        >
          <SettingsDropdown
            startingValue={portfolioGoal}
            options={PortfolioGoalOptions}
            setOption={setPortfolioGoal}
          />
          <Button
            size="sm"
            onClick={() =>
              mutate({ userId, portfolioId, name: null, budget: null, goal: portfolioGoal, status: null })
            }
          >
            Save
          </Button>
        </SettingRow>

        <SettingRow
          label="Status"
          description="Where the portfolio stands in the works pipeline."
        >
          <SettingsDropdown
            startingValue={portfolioStatus}
            options={PortfolioStatusOptions}
            setOption={setPortfolioStatus}
          />
          <Button
            size="sm"
            onClick={() =>
              mutate({ userId, portfolioId, name: null, budget: null, goal: null, status: portfolioStatus })
            }
          >
            Save
          </Button>
        </SettingRow>
      </div>
    </div>
  );
}
