<?php
require_once __DIR__ . '/helpers.php';
require_once __DIR__ . '/fiscal_es.php';

function doc_type_label(string $type): string {
  return $type === 'invoice' ? 'Factura' : 'Presupuesto';
}

function default_prefix(string $type, int $year): string {
  return ($type === 'invoice' ? 'F-' : 'P-') . $year . '-';
}

function ensure_part2_tables(): void {
  $pdo = db();

  $pdo->exec("
    CREATE TABLE IF NOT EXISTS doc_series(
      id INT AUTO_INCREMENT PRIMARY KEY,
      doc_type ENUM('quote','invoice') NOT NULL,
      year INT NOT NULL,
      prefix VARCHAR(40) NOT NULL,
      next_number INT NOT NULL DEFAULT 1,
      UNIQUE KEY uniq_type_year (doc_type, year)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
  ");

  $pdo->exec("
    CREATE TABLE IF NOT EXISTS documents(
      id INT AUTO_INCREMENT PRIMARY KEY,
      doc_type ENUM('quote','invoice') NOT NULL,
      series_prefix VARCHAR(40) NOT NULL,
      series_number INT NOT NULL,
      doc_code VARCHAR(60) NOT NULL UNIQUE,
      client_id INT NOT NULL,
      issue_date DATE NOT NULL,
      due_date DATE NULL,
      status ENUM('draft','sent','accepted','paid','cancelled') NOT NULL DEFAULT 'draft',
      notes TEXT NULL,
      currency VARCHAR(10) NOT NULL DEFAULT 'EUR',
      subtotal DECIMAL(12,2) NOT NULL DEFAULT 0,
      tax_total DECIMAL(12,2) NOT NULL DEFAULT 0,
      total DECIMAL(12,2) NOT NULL DEFAULT 0,
      created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
      updated_at TIMESTAMP NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
      INDEX idx_type_date (doc_type, issue_date),
      INDEX idx_client (client_id),
      CONSTRAINT fk_documents_client FOREIGN KEY (client_id) REFERENCES clients(id) ON DELETE RESTRICT
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
  ");

  $pdo->exec("
    CREATE TABLE IF NOT EXISTS document_lines(
      id INT AUTO_INCREMENT PRIMARY KEY,
      document_id INT NOT NULL,
      line_no INT NOT NULL,
      description VARCHAR(255) NOT NULL,
      qty DECIMAL(12,3) NOT NULL DEFAULT 1,
      unit_price DECIMAL(12,2) NOT NULL DEFAULT 0,
      vat_rate INT NOT NULL DEFAULT 21,
      line_subtotal DECIMAL(12,2) NOT NULL DEFAULT 0,
      line_tax DECIMAL(12,2) NOT NULL DEFAULT 0,
      line_total DECIMAL(12,2) NOT NULL DEFAULT 0,
      INDEX idx_doc (document_id),
      CONSTRAINT fk_lines_doc FOREIGN KEY (document_id) REFERENCES documents(id) ON DELETE CASCADE
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
  ");

  $pdo->exec("
    CREATE TABLE IF NOT EXISTS company_settings(
      id INT AUTO_INCREMENT PRIMARY KEY,
      company_name VARCHAR(160) NOT NULL DEFAULT 'TU EMPRESA',
      nif_cif VARCHAR(30) NULL,
      address VARCHAR(255) NULL,
      phone VARCHAR(40) NULL,
      email VARCHAR(120) NULL,
      iban VARCHAR(60) NULL,
      footer_note VARCHAR(255) NULL,
      logo_path VARCHAR(255) NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
  ");

  // seed inicial
  $c = (int)($pdo->query("SELECT COUNT(*) AS c FROM company_settings")->fetch()['c'] ?? 0);
  if ($c === 0) {
    $pdo->exec("INSERT INTO company_settings(company_name, footer_note) VALUES ('TU EMPRESA','Gracias por su confianza')");
  }
}

function get_company(): array {
  $st = db()->query("SELECT * FROM company_settings ORDER BY id ASC LIMIT 1");
  $row = $st->fetch();
  return $row ?: ['company_name' => 'TU EMPRESA'];
}

function update_company(array $data): void {
  $pdo = db();
  $cur = get_company();
  $id = (int)($cur['id'] ?? 1);

  $vals = [
    'company_name' => trim((string)($data['company_name'] ?? ($cur['company_name'] ?? 'TU EMPRESA'))),
    'nif_cif'      => trim((string)($data['nif_cif'] ?? ($cur['nif_cif'] ?? ''))),
    'address'      => trim((string)($data['address'] ?? ($cur['address'] ?? ''))),
    'phone'        => trim((string)($data['phone'] ?? ($cur['phone'] ?? ''))),
    'email'        => trim((string)($data['email'] ?? ($cur['email'] ?? ''))),
    'iban'         => trim((string)($data['iban'] ?? ($cur['iban'] ?? ''))),
    'footer_note'  => trim((string)($data['footer_note'] ?? ($cur['footer_note'] ?? ''))),
    'logo_path'    => trim((string)($data['logo_path'] ?? ($cur['logo_path'] ?? ''))),
  ];

  $pdo->prepare("UPDATE company_settings
      SET company_name=?, nif_cif=?, address=?, phone=?, email=?, iban=?, footer_note=?, logo_path=?
      WHERE id=?")
    ->execute([
      $vals['company_name'],
      $vals['nif_cif'] ?: null,
      $vals['address'] ?: null,
      $vals['phone'] ?: null,
      $vals['email'] ?: null,
      $vals['iban'] ?: null,
      $vals['footer_note'] ?: null,
      $vals['logo_path'] ?: null,
      $id
    ]);
}

function next_doc_code(string $type): array {
  $year = (int)date('Y');
  $pdo = db();
  $pdo->beginTransaction();
  try {
    $sel = $pdo->prepare("SELECT id, prefix, next_number FROM doc_series WHERE doc_type=? AND year=? FOR UPDATE");
    $sel->execute([$type, $year]);
    $row = $sel->fetch();

    if (!$row) {
      $prefix = default_prefix($type, $year);
      $pdo->prepare("INSERT INTO doc_series(doc_type, year, prefix, next_number) VALUES(?,?,?,2)")
          ->execute([$type, $year, $prefix]);
      $number = 1;
    } else {
      $prefix = $row['prefix'];
      $number = (int)$row['next_number'];
      $pdo->prepare("UPDATE doc_series SET next_number=? WHERE id=?")
          ->execute([$number + 1, (int)$row['id']]);
    }

    $code = $prefix . str_pad((string)$number, 4, '0', STR_PAD_LEFT);
    $pdo->commit();
    return ['prefix' => $prefix, 'number' => $number, 'code' => $code];
  } catch (Throwable $e) {
    $pdo->rollBack();
    throw $e;
  }
}

function calc_totals(array $lines): array {
  $subtotal = 0.0;
  $tax_total = 0.0;

  foreach ($lines as &$ln) {
    $qty  = (float)($ln['qty'] ?? 1);
    $unit = (float)($ln['unit_price'] ?? 0);
    $vat  = (int)($ln['vat_rate'] ?? 21);

    $line_sub  = round($qty * $unit, 2);
    $line_tax  = round($line_sub * ($vat / 100.0), 2);
    $line_total= round($line_sub + $line_tax, 2);

    $ln['line_subtotal'] = $line_sub;
    $ln['line_tax'] = $line_tax;
    $ln['line_total'] = $line_total;

    $subtotal += $line_sub;
    $tax_total += $line_tax;
  }

  return [
    'subtotal' => round($subtotal, 2),
    'tax_total' => round($tax_total, 2),
    'total' => round($subtotal + $tax_total, 2),
    'lines' => $lines
  ];
}
