import type { CompanyProfileInput } from "@mrp/shared";
import { useEffect, useState } from "react";

import { useAuth } from "../../auth/AuthProvider";
import { api } from "../../lib/api";
import { useTheme } from "../../theme/ThemeProvider";

export function CompanySettingsPage() {
  const { token } = useAuth();
  const { applyBrandProfile } = useTheme();
  const [form, setForm] = useState<CompanyProfileInput | null>(null);
  const [companyId, setCompanyId] = useState<string | null>(null);
  const [logoUrl, setLogoUrl] = useState<string | null>(null);
  const [status, setStatus] = useState<string>("Loading company profile...");

  async function loadLogoPreview(nextToken: string, logoFileId: string | null) {
    if (!logoFileId) {
      setLogoUrl((current) => {
        if (current?.startsWith("blob:")) {
          window.URL.revokeObjectURL(current);
        }
        return null;
      });
      return;
    }

    const blob = await api.getFileContentBlob(nextToken, logoFileId);
    const objectUrl = window.URL.createObjectURL(blob);
    setLogoUrl((current) => {
      if (current?.startsWith("blob:")) {
        window.URL.revokeObjectURL(current);
      }
      return objectUrl;
    });
  }

  useEffect(() => {
    if (!token) {
      return;
    }

    let active = true;

    api.getCompanyProfile(token).then((profile) => {
      setCompanyId(profile.id);
      setForm({
        companyName: profile.companyName,
        legalName: profile.legalName,
        email: profile.email,
        phone: profile.phone,
        website: profile.website,
        taxId: profile.taxId,
        addressLine1: profile.addressLine1,
        addressLine2: profile.addressLine2,
        city: profile.city,
        state: profile.state,
        postalCode: profile.postalCode,
        country: profile.country,
        theme: profile.theme,
      });
      applyBrandProfile(profile);
      setStatus("Company profile loaded.");

      if (profile.theme.logoFileId) {
        loadLogoPreview(token, profile.theme.logoFileId)
          .then(() => {
            if (!active) {
              return;
            }
          })
          .catch(() => {
            if (active) {
              setLogoUrl(null);
            }
          });
      } else {
        setLogoUrl(null);
      }
    });

    return () => {
      active = false;
    };
  }, [applyBrandProfile, token]);

  useEffect(() => {
    return () => {
      if (logoUrl?.startsWith("blob:")) {
        window.URL.revokeObjectURL(logoUrl);
      }
    };
  }, [logoUrl]);

  if (!form || !token) {
    return <div className="rounded-[28px] border border-line/70 bg-surface/90 p-6 text-sm text-muted shadow-panel">{status}</div>;
  }

  async function handleSave(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault();
    if (!token || !form) {
      return;
    }
    const profile = await api.updateCompanyProfile(token, form);
    applyBrandProfile(profile);
    await loadLogoPreview(token, profile.theme.logoFileId);
    setStatus("Company settings saved.");
  }

  async function handleLogoUpload(event: React.ChangeEvent<HTMLInputElement>) {
    const file = event.target.files?.[0];
    if (!file || !companyId || !token) {
      return;
    }

    const attachment = await api.uploadFile(token, file, "company-profile", companyId);
    setForm((current) =>
      current
        ? {
            ...current,
            theme: {
              ...current.theme,
              logoFileId: attachment.id,
            },
          }
        : current
    );
    await loadLogoPreview(token, attachment.id);
    setStatus("Logo uploaded. Save to persist it on the profile.");
  }

  async function handlePdfPreview() {
    if (!token) {
      return;
    }

    const blob = await api.getCompanyProfilePreviewPdf(token);
    const objectUrl = window.URL.createObjectURL(blob);
    window.open(objectUrl, "_blank", "noopener,noreferrer");
    window.setTimeout(() => window.URL.revokeObjectURL(objectUrl), 60_000);
  }

  function updateField<Key extends keyof CompanyProfileInput>(key: Key, value: CompanyProfileInput[Key]) {
    setForm((current) => (current ? { ...current, [key]: value } : current));
  }

  return (
    <form className="space-y-6" onSubmit={handleSave}>
      <section className="rounded-[28px] border border-line/70 bg-surface/90 p-6 shadow-panel backdrop-blur 2xl:p-7">
        <div className="flex flex-col gap-6 lg:flex-row lg:items-start lg:justify-between">
          <div>
            <p className="text-xs font-semibold uppercase tracking-[0.24em] text-muted">Company Profile</p>
            <h3 className="mt-3 text-xl font-bold text-text">Branding and legal identity</h3>
            <p className="mt-2 max-w-2xl text-sm text-muted">Every internal document and PDF template will inherit its company identity from this profile.</p>
          </div>
          <div className="rounded-3xl border border-dashed border-line/70 bg-page/80 p-4">
            {logoUrl ? <img alt="Company logo" className="h-20 w-20 rounded-2xl object-cover" src={logoUrl} /> : <div className="flex h-20 w-20 items-center justify-center rounded-2xl bg-brand text-sm font-bold text-white">LOGO</div>}
            <label className="mt-3 block cursor-pointer text-sm font-semibold text-brand">
              Upload logo
              <input className="hidden" type="file" accept="image/*" onChange={handleLogoUpload} />
            </label>
          </div>
        </div>
        <div className="mt-6 grid gap-4 xl:grid-cols-2 2xl:grid-cols-3">
          {[
            ["companyName", "Company name"],
            ["legalName", "Legal name"],
            ["email", "Email"],
            ["phone", "Phone"],
            ["website", "Website"],
            ["taxId", "Tax ID"],
            ["addressLine1", "Address line 1"],
            ["addressLine2", "Address line 2"],
            ["city", "City"],
            ["state", "State"],
            ["postalCode", "Postal code"],
            ["country", "Country"],
          ].map(([key, label]) => (
            <label key={key} className="block">
              <span className="mb-2 block text-sm font-semibold text-text">{label}</span>
              <input
                value={String(form[key as keyof CompanyProfileInput])}
                onChange={(event) => updateField(key as keyof CompanyProfileInput, event.target.value as never)}
            className="w-full rounded-2xl border border-line/70 bg-page px-2 py-2 text-text outline-none transition focus:border-brand"
              />
            </label>
          ))}
        </div>
      </section>
      <section className="rounded-[28px] border border-line/70 bg-surface/90 p-6 shadow-panel backdrop-blur 2xl:p-7">
        <p className="text-xs font-semibold uppercase tracking-[0.24em] text-muted">Theme</p>
        <div className="mt-5 grid gap-4 md:grid-cols-2 2xl:grid-cols-4">
          <label className="block">
            <span className="mb-2 block text-sm font-semibold text-text">Primary color</span>
            <input type="color" value={form.theme.primaryColor} onChange={(event) => updateField("theme", { ...form.theme, primaryColor: event.target.value })} className="h-12 w-full rounded-2xl border border-line/70 bg-page p-2" />
          </label>
          <label className="block">
            <span className="mb-2 block text-sm font-semibold text-text">Accent color</span>
            <input type="color" value={form.theme.accentColor} onChange={(event) => updateField("theme", { ...form.theme, accentColor: event.target.value })} className="h-12 w-full rounded-2xl border border-line/70 bg-page p-2" />
          </label>
          <label className="block">
            <span className="mb-2 block text-sm font-semibold text-text">Surface color</span>
            <input type="color" value={form.theme.surfaceColor} onChange={(event) => updateField("theme", { ...form.theme, surfaceColor: event.target.value })} className="h-12 w-full rounded-2xl border border-line/70 bg-page p-2" />
          </label>
          <label className="block">
            <span className="mb-2 block text-sm font-semibold text-text">Font family</span>
            <input value={form.theme.fontFamily} onChange={(event) => updateField("theme", { ...form.theme, fontFamily: event.target.value })} className="w-full rounded-2xl border border-line/70 bg-page px-2 py-2 text-text outline-none transition focus:border-brand" />
          </label>
        </div>
        <div className="mt-5 flex flex-col gap-3 rounded-2xl border border-line/70 bg-page/70 px-4 py-4 lg:flex-row lg:items-center lg:justify-between">
          <span className="min-w-0 text-sm text-muted">{status}</span>
          <div className="flex flex-wrap gap-3">
            <button
              type="button"
              onClick={handlePdfPreview}
              className="rounded-2xl border border-line/70 px-4 py-3 text-sm font-semibold text-text"
            >
              Preview PDF
            </button>
            <button type="submit" className="rounded-2xl bg-brand px-3 py-2 text-sm font-semibold text-white">
              Save changes
            </button>
          </div>
        </div>
      </section>
    </form>
  );
}
